/*
 * Copyright (C) 2010 NXP Semiconductors
 *
 * 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.
 */

/*!
 * \file phLibNfc_ndef_raw.c

 * Project: NFC FRI 1.1
 *
 * $Date: Mon Dec 13 14:14:15 2010 $
 * $Author: ing02260 $
 * $Revision: 1.74 $
 * $Aliases:  $
 *
 */

/*
************************* Header Files ****************************************
*/

#include <phLibNfcStatus.h>
#include <phLibNfc.h>
#include <phHal4Nfc.h>
#include <phOsalNfc.h>
#include <phLibNfc_Internal.h>
#include <phLibNfc_ndef_raw.h>
#include <phLibNfc_initiator.h>
#include <phLibNfc_discovery.h>
#include <phFriNfc_NdefReg.h>

/*
*************************** Macro's  ****************************************
*/

#ifndef STATIC_DISABLE
#define STATIC static
#else
//#undef STATIC
#define STATIC 
#endif

#define     TOPAZ_NDEF_BITMASK             0x10U
#define     TOPAZ_LEN_BITMASK              0x02U
#define     TOPAZ_DYNAMIC_LEN               460U
#define     TOPAZ_STATIC_CARD_LEN           128U
#define     MIFARE_STD_BLOCK_SIZE          0x10U
/*
*************************** Global Variables **********************************
*/
phLibNfc_Ndef_Info_t NdefInfo;
phFriNfc_NdefRecord_t *pNdefRecord=NULL;
/*
*************************** Static Function Declaration ***********************
*/

/* Response callback for Check Ndef */
STATIC 
void phLibNfc_Ndef_CheckNdef_Cb(void *pContext, NFCSTATUS status);

/* Response callback for Ndef Write */
STATIC 
void phLibNfc_Ndef_Write_Cb(void* Context,NFCSTATUS status);

/* Response callback for Ndef Read*/
STATIC 
void phLibNfc_Ndef_Read_Cb(void* Context,NFCSTATUS status);

/* Response callback forNdef Format*/
STATIC 
void phLibNfc_Ndef_format_Cb(void *Context,NFCSTATUS status);

#ifdef LIBNFC_READONLY_NDEF
STATIC
void
phLibNfc_Ndef_ReadOnly_Cb (
    void        *p_context,
    NFCSTATUS   status);
#endif /* #ifdef LIBNFC_READONLY_NDEF */

/* Response callback for Search Ndef Content */
STATIC
void phLibNfc_Ndef_SrchNdefCnt_Cb(void *context, NFCSTATUS status);

/* Response callback for Ndef Record Type Discovery */
STATIC
void phLibNfc_Ndef_Rtd_Cb( void *CallBackParam);

/* Response callback for Check Ndef timer callback */
STATIC void CheckNdef_timer_cb(uint32_t timer_id, void *pContext);

/*Callback for Presence check call from Chk Ndef*/
STATIC void phLibNfc_Ndef_ChkNdef_Pchk_Cb(void   *pContext,
                                NFCSTATUS  status
                                );
/*
*************************** Function Definitions ******************************
*/

/**
* This function reads an NDEF message from  already connected tag.
* the NDEF message  is read starting after the position of the
* last read operation of the same tag during current session.
*/

NFCSTATUS phLibNfc_Ndef_Read( phLibNfc_Handle                   hRemoteDevice,
                            phNfc_sData_t                      *psRd,
                            phLibNfc_Ndef_EOffset_t             Offset,
                            pphLibNfc_RspCb_t                   pNdefRead_RspCb,
                            void*                               pContext
                            )
{
    NFCSTATUS RetVal = NFCSTATUS_FAILED;
    if((NULL == gpphLibContext)|| 
        (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
    {
        RetVal = NFCSTATUS_NOT_INITIALISED;
    }
    else if((NULL == psRd) || (NULL == pNdefRead_RspCb)
        || (NULL == psRd->buffer)
        || (0 == psRd->length)
        || (NULL == pContext)
        || (0 == hRemoteDevice))
    {
        RetVal= NFCSTATUS_INVALID_PARAMETER;
    }    
    else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown)
    {
        RetVal = NFCSTATUS_SHUTDOWN;
    }
    else if(0 == gpphLibContext->Connected_handle)
    {   /*presently no target or tag is connected*/ 
        RetVal=NFCSTATUS_TARGET_NOT_CONNECTED;        
    }
    else if(hRemoteDevice != gpphLibContext->Connected_handle)
    {   /*This handle of the device sent by application is not connected */ 
        RetVal=NFCSTATUS_INVALID_HANDLE;        
    }
    else if((TRUE == gpphLibContext->status.GenCb_pending_status)       
            ||(NULL!=gpphLibContext->CBInfo.pClientRdNdefCb)
            ||(CHK_NDEF_NOT_DONE == gpphLibContext->ndef_cntx.is_ndef))
    {
        /*Previous callback is pending*/
        RetVal = NFCSTATUS_REJECTED;
    }
    else if(gpphLibContext->ndef_cntx.is_ndef == FALSE)
    {
        /*no Ndef Support in tag*/
         RetVal = NFCSTATUS_NON_NDEF_COMPLIANT;
    }
    else if((gpphLibContext->ndef_cntx.is_ndef == TRUE)
        &&(0 == gpphLibContext->ndef_cntx.NdefActualSize))
    {
        /*Card is empty- So Returning length as zero*/
        psRd->length = 0;
        RetVal = NFCSTATUS_SUCCESS;
    }
#ifdef LLCP_TRANSACT_CHANGES
    else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state)
            && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state))
    {
        RetVal= NFCSTATUS_BUSY;
    }
#endif /* #ifdef LLCP_TRANSACT_CHANGES */
    else
    {
        gpphLibContext->psRemoteDevList->psRemoteDevInfo->SessionOpened = SESSION_OPEN;
        gpphLibContext->ndef_cntx.eLast_Call = NdefRd;
        if((((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType == 
            phHal_eMifare_PICC) && (((phHal_sRemoteDevInformation_t*)
            hRemoteDevice)->RemoteDevInfo.Iso14443A_Info.Sak != 0)&&
            ((NULL == gpphLibContext->psBufferedAuth)
            ||(phHal_eMifareAuthentA == gpphLibContext->psBufferedAuth->cmd.MfCmd))
            )
        {
            if(NULL != gpphLibContext->psBufferedAuth)
            {
                if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer)
                {
                    phOsalNfc_FreeMemory(
                        gpphLibContext->psBufferedAuth->sRecvData.buffer);
                }
                if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer)
                {
                    phOsalNfc_FreeMemory(
                        gpphLibContext->psBufferedAuth->sSendData.buffer);
                }
                phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth);
            }
            gpphLibContext->psBufferedAuth
                =(phLibNfc_sTransceiveInfo_t *) 
                phOsalNfc_GetMemory(sizeof(phLibNfc_sTransceiveInfo_t));            
            gpphLibContext->psBufferedAuth->addr = 
             (uint8_t)gpphLibContext->ndef_cntx.psNdefMap
             ->StdMifareContainer.currentBlock;
            gpphLibContext->psBufferedAuth->cmd.MfCmd = phHal_eMifareRead16;
            gpphLibContext->psBufferedAuth->sSendData.length
                = 0;            
            gpphLibContext->psBufferedAuth->sRecvData.length
                = MIFARE_STD_BLOCK_SIZE;                      
            gpphLibContext->psBufferedAuth->sRecvData.buffer
                = (uint8_t *)phOsalNfc_GetMemory(MIFARE_STD_BLOCK_SIZE);
            gpphLibContext->psBufferedAuth->sSendData.buffer
             = (uint8_t *)phOsalNfc_GetMemory(MIFARE_STD_BLOCK_SIZE);
        }
        if(eLibNfcHalStatePresenceChk !=
                gpphLibContext->LibNfcState.next_state)
        {
            uint8_t     cr_index = 0;
            gpphLibContext->ndef_cntx.psUpperNdefMsg = psRd;
            for (cr_index = 0; cr_index < PH_FRINFC_NDEFMAP_CR; cr_index++)
            {
                RetVal= phFriNfc_NdefMap_SetCompletionRoutine(
                                    gpphLibContext->ndef_cntx.psNdefMap,
                                    cr_index,
                                    phLibNfc_Ndef_Read_Cb,
                                    (void *)gpphLibContext);

            }
            gpphLibContext->ndef_cntx.NdefContinueRead =(uint8_t) ((phLibNfc_Ndef_EBegin==Offset) ?
                                                    PH_FRINFC_NDEFMAP_SEEK_BEGIN :
                                                    PH_FRINFC_NDEFMAP_SEEK_CUR);
            /* call below layer Ndef Read*/
            RetVal = phFriNfc_NdefMap_RdNdef(gpphLibContext->ndef_cntx.psNdefMap,
                            gpphLibContext->ndef_cntx.psUpperNdefMsg->buffer,
                            (uint32_t*)&gpphLibContext->ndef_cntx.psUpperNdefMsg->length,
                            gpphLibContext->ndef_cntx.NdefContinueRead);

            RetVal = PHNFCSTATUS(RetVal);
            if(NFCSTATUS_INSUFFICIENT_STORAGE == RetVal)
            {
                gpphLibContext->ndef_cntx.psUpperNdefMsg->length = 0;
                RetVal = NFCSTATUS_SUCCESS;
            }
        }
        else
        {
             gpphLibContext->CBInfo.pClientRdNdefCb= NULL;
             RetVal = NFCSTATUS_PENDING;
        }
        if(NFCSTATUS_PENDING == RetVal)
        {
            gpphLibContext->CBInfo.pClientRdNdefCb = pNdefRead_RspCb;
            gpphLibContext->CBInfo.pClientRdNdefCntx = pContext;
            gpphLibContext->status.GenCb_pending_status=TRUE;
			gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction; 
           
        }
        else if (NFCSTATUS_SUCCESS == RetVal)
        {
            RetVal= NFCSTATUS_SUCCESS;
        }
        else
        {
            /*Ndef read failed*/
            RetVal = NFCSTATUS_FAILED;
        }
    }
    return RetVal;
}
/* Response callback for phLibNfc_Ndef_Read */
STATIC
void phLibNfc_Ndef_Read_Cb(void* Context,NFCSTATUS status)
{
    NFCSTATUS               RetStatus = NFCSTATUS_SUCCESS;
    pphLibNfc_RspCb_t       pClientCb=NULL;
    phLibNfc_LibContext_t   *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)Context;
    void                    *pUpperLayerContext=NULL;
    phHal_sRemoteDevInformation_t   *ps_rem_dev_info = NULL;

    if(pLibNfc_Ctxt != gpphLibContext)
    {
        /*wrong context returned*/
        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
    }
    else
    {
        if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
        {   /*shutdown called before completion of Ndef read allow
              shutdown to happen */
            phLibNfc_Pending_Shutdown();
            RetStatus = NFCSTATUS_SHUTDOWN;    
        }
        else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
        {
            RetStatus = NFCSTATUS_ABORTED;
        }
        else
        {
            gpphLibContext->status.GenCb_pending_status = FALSE;
            if (gpphLibContext->psBufferedAuth != NULL && gpphLibContext->ndef_cntx.psNdefMap != NULL) {
                   gpphLibContext->psBufferedAuth->addr = (uint8_t)
                   gpphLibContext->ndef_cntx.psNdefMap->StdMifareContainer.currentBlock;
            }

            if(NFCSTATUS_FAILED == status )
            {
                /*During Ndef read operation tag was not present in RF
                field of reader*/
                RetStatus = NFCSTATUS_FAILED; 
                gpphLibContext->LastTrancvSuccess = FALSE;
                gpphLibContext->ndef_cntx.is_ndef = FALSE;
                ps_rem_dev_info = (phHal_sRemoteDevInformation_t *)
                                    gpphLibContext->Connected_handle;
                if ((phHal_eMifare_PICC == ps_rem_dev_info->RemDevType) && 
                    (0x08 == (ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak & 0x08)))
                {

                    /* card type is mifare 1k/4k, then reconnect */
                    RetStatus = phHal4Nfc_Connect(gpphLibContext->psHwReference,  
                                ps_rem_dev_info,
                                (pphHal4Nfc_ConnectCallback_t)
                                phLibNfc_Reconnect_Mifare_Cb,
                                (void *)gpphLibContext);
                }

            }  
            else if(status == NFCSTATUS_SUCCESS)
            {
                gpphLibContext->LastTrancvSuccess = TRUE;
                RetStatus = NFCSTATUS_SUCCESS;
            }
		    else
		    {
                gpphLibContext->LastTrancvSuccess = FALSE;
				RetStatus = NFCSTATUS_FAILED;
			}
        }
        /*update the current state as connected*/
        phLibNfc_UpdateCurState(status,gpphLibContext);

        pClientCb = gpphLibContext->CBInfo.pClientRdNdefCb;
        pUpperLayerContext = gpphLibContext->CBInfo.pClientRdNdefCntx;

        gpphLibContext->CBInfo.pClientRdNdefCb = NULL;
        gpphLibContext->CBInfo.pClientRdNdefCntx = NULL;
        if(NFCSTATUS_PENDING != RetStatus)
        {
            if (NULL != pClientCb)
            {
                /*Notify to upper layer status and read bytes*/
                pClientCb(pUpperLayerContext,RetStatus);            
            }
        }
    }
    return;
}

/**
* Write NDEF to a tag.
*
* This function allows the user to write a NDEF data to already connected NFC
* tag.Function writes   a complete NDEF message to a tag. If a NDEF message
* already exists in the tag, it will be overwritten. When the transaction is
* complete,a notification callback is notified.
*/
NFCSTATUS phLibNfc_Ndef_Write(
                            phLibNfc_Handle          hRemoteDevice,
                            phNfc_sData_t           *psWr,                              
                            pphLibNfc_RspCb_t        pNdefWrite_RspCb,
                            void*                    pContext
                            )
{
    NFCSTATUS RetVal = NFCSTATUS_FAILED;
    uint8_t             NdefWriteType=0xFF;
    /*LibNfc is initilized or not */
    if((NULL == gpphLibContext)||
        (gpphLibContext->LibNfcState.cur_state
                            == eLibNfcHalStateShutdown))
    {   
        RetVal = NFCSTATUS_NOT_INITIALISED;
    }/*Check for application has sent the valid parameters*/
    else if((NULL == psWr) || (NULL == pNdefWrite_RspCb)
        || (NULL == psWr->buffer)
        || (NULL == pContext)
        || (0 ==hRemoteDevice))
    {
        RetVal= NFCSTATUS_INVALID_PARAMETER;
    }   
    else if(gpphLibContext->LibNfcState.next_state
                            == eLibNfcHalStateShutdown)
    {   /* Lib Nfc Shutdown*/
        RetVal= NFCSTATUS_SHUTDOWN;
    }
    else if(0 == gpphLibContext->Connected_handle)
    {       
        RetVal=NFCSTATUS_TARGET_NOT_CONNECTED;        
    }
    else if(hRemoteDevice != gpphLibContext->Connected_handle)
    {       
        RetVal=NFCSTATUS_INVALID_HANDLE;        
    }    
    else if((TRUE == gpphLibContext->status.GenCb_pending_status)||        
           (gpphLibContext->ndef_cntx.is_ndef == CHK_NDEF_NOT_DONE))
    {
         /* Previous callback is pending or Tag is not NDEF tag*/
        RetVal = NFCSTATUS_REJECTED;
        PHDBG_INFO("LIbNfc:Previous Callback is Pending");
    }
    else if(FALSE == gpphLibContext->ndef_cntx.is_ndef)
    {
        RetVal = NFCSTATUS_NON_NDEF_COMPLIANT;
    }
    else if(psWr->length > gpphLibContext->ndef_cntx.NdefLength)
    {
        RetVal = NFCSTATUS_NOT_ENOUGH_MEMORY;
    }
#ifdef LLCP_TRANSACT_CHANGES
    else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state)
            && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state))
    {
        RetVal= NFCSTATUS_BUSY;
    }
#endif /* #ifdef LLCP_TRANSACT_CHANGES */
    else
    {
        uint8_t         cr_index = 0;
        gpphLibContext->ndef_cntx.psUpperNdefMsg = psWr;
        gpphLibContext->ndef_cntx.AppWrLength= psWr->length;
        gpphLibContext->ndef_cntx.eLast_Call = NdefWr;
        gpphLibContext->psRemoteDevList->psRemoteDevInfo->SessionOpened 
            = SESSION_OPEN;
        if((((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType == 
               phHal_eMifare_PICC) && (((phHal_sRemoteDevInformation_t*)
               hRemoteDevice)->RemoteDevInfo.Iso14443A_Info.Sak != 0)&&
               ((NULL == gpphLibContext->psBufferedAuth)
                ||(phHal_eMifareAuthentA == 
                   gpphLibContext->psBufferedAuth->cmd.MfCmd))
               )
        {
            if(NULL != gpphLibContext->psBufferedAuth)
            {
                if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer)
                {
                    phOsalNfc_FreeMemory(
                        gpphLibContext->psBufferedAuth->sRecvData.buffer);
                }
                if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer)
                {
                    phOsalNfc_FreeMemory(
                        gpphLibContext->psBufferedAuth->sSendData.buffer);
                }
                phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth);
            }
            gpphLibContext->psBufferedAuth
                =(phLibNfc_sTransceiveInfo_t *) 
                phOsalNfc_GetMemory(sizeof(phLibNfc_sTransceiveInfo_t));            
            gpphLibContext->psBufferedAuth->addr = 
             (uint8_t)gpphLibContext->ndef_cntx.psNdefMap
             ->StdMifareContainer.currentBlock;
            gpphLibContext->psBufferedAuth->cmd.MfCmd = phHal_eMifareRead16;
            gpphLibContext->psBufferedAuth->sSendData.length
                = 0;            
            gpphLibContext->psBufferedAuth->sRecvData.length
                = MIFARE_STD_BLOCK_SIZE;                      
            gpphLibContext->psBufferedAuth->sRecvData.buffer
                = (uint8_t *)phOsalNfc_GetMemory(MIFARE_STD_BLOCK_SIZE);  
             gpphLibContext->psBufferedAuth->sSendData.buffer
                = (uint8_t *)phOsalNfc_GetMemory(MIFARE_STD_BLOCK_SIZE);
        }
        if(eLibNfcHalStatePresenceChk ==
                gpphLibContext->LibNfcState.next_state)
        {
            gpphLibContext->CBInfo.pClientWrNdefCb = NULL;
            RetVal = NFCSTATUS_PENDING;
        }
        else
        {
            for (cr_index = 0; cr_index < PH_FRINFC_NDEFMAP_CR; cr_index++)
            {
                /* Registering the Completion Routine.*/
                RetVal= phFriNfc_NdefMap_SetCompletionRoutine(
                                    gpphLibContext->ndef_cntx.psNdefMap,
                                    cr_index,
                                    phLibNfc_Ndef_Write_Cb,
                                    (void *)gpphLibContext);

            }
            if(0 == psWr->length)
            {
                 /* Length of bytes to be written Zero- Erase the Tag  */
                RetVal = phFriNfc_NdefMap_EraseNdef(gpphLibContext->ndef_cntx.psNdefMap);
            }
            else
            {
                /*Write from beginning or current location*/
                NdefWriteType = PH_FRINFC_NDEFMAP_SEEK_BEGIN; 
                /*Call FRI Ndef Write*/
                RetVal=phFriNfc_NdefMap_WrNdef(gpphLibContext->ndef_cntx.psNdefMap,
                            gpphLibContext->ndef_cntx.psUpperNdefMsg->buffer,
                            (uint32_t*)&gpphLibContext->ndef_cntx.psUpperNdefMsg->length,
                            NdefWriteType);
            }
            if(NFCSTATUS_PENDING == RetVal)
            {
                gpphLibContext->CBInfo.pClientWrNdefCb = pNdefWrite_RspCb;
                gpphLibContext->CBInfo.pClientWrNdefCntx = pContext;
                gpphLibContext->status.GenCb_pending_status=TRUE;
                gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction;
            }
            else
            {
                RetVal = NFCSTATUS_FAILED;
            }
        }    
    }
    return RetVal;
}

/* Response callback for phLibNfc_Ndef_Write */
STATIC
void phLibNfc_Ndef_Write_Cb(void* Context,NFCSTATUS status)
{

    pphLibNfc_RspCb_t       pClientCb=NULL;
    phLibNfc_LibContext_t   *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)Context;
    void                    *pUpperLayerContext=NULL;
    phHal_sRemoteDevInformation_t   *ps_rem_dev_info = NULL;

    if(pLibNfc_Ctxt != gpphLibContext)
    {   /*wrong context returned*/
        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
    }
    else
    {
        if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
        {   /*shutdown called before completion of Ndef write allow
              shutdown to happen */
            phLibNfc_Pending_Shutdown();
            status = NFCSTATUS_SHUTDOWN;    
        }
        else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
        {
            status = NFCSTATUS_ABORTED;
        }
        else
        {
            gpphLibContext->status.GenCb_pending_status = FALSE;
            if (gpphLibContext->psBufferedAuth != NULL && gpphLibContext->ndef_cntx.psNdefMap != NULL) {
                gpphLibContext->psBufferedAuth->addr = (uint8_t)
                    gpphLibContext->ndef_cntx.psNdefMap->TLVStruct.NdefTLVBlock;
            }
            if(status == NFCSTATUS_FAILED )
            {
				status = NFCSTATUS_FAILED;
                gpphLibContext->LastTrancvSuccess = FALSE;
                /*During Ndef write operation tag was not present in RF
                field of reader*/
                ps_rem_dev_info = (phHal_sRemoteDevInformation_t *)
                                    gpphLibContext->Connected_handle;
               if ((phHal_eMifare_PICC == ps_rem_dev_info->RemDevType) && 
                    (0x08 == (ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak & 0x08)))
                {

               
                    /* card type is mifare 1k/4k, then reconnect */
                    status = phHal4Nfc_Connect(gpphLibContext->psHwReference,  
                                ps_rem_dev_info,
                                (pphHal4Nfc_ConnectCallback_t)
                                phLibNfc_Reconnect_Mifare_Cb,
                                (void *)gpphLibContext);
                }
            }
            else if( status== NFCSTATUS_SUCCESS)
            {
                gpphLibContext->LastTrancvSuccess = TRUE;
                status = NFCSTATUS_SUCCESS;
                if(gpphLibContext->ndef_cntx.AppWrLength >
                                 gpphLibContext->ndef_cntx.NdefLength)
                {
                    status = NFCSTATUS_NOT_ENOUGH_MEMORY;
                }
                else
                {
                    pLibNfc_Ctxt->ndef_cntx.NdefActualSize = 
                                    pLibNfc_Ctxt->ndef_cntx.psUpperNdefMsg->length;
                }
            }           
            else
            {
                gpphLibContext->LastTrancvSuccess = FALSE;
				status = NFCSTATUS_FAILED;;
			}
        }
        phLibNfc_UpdateCurState(status,gpphLibContext);

        pClientCb = gpphLibContext->CBInfo.pClientWrNdefCb;
        pUpperLayerContext = gpphLibContext->CBInfo.pClientWrNdefCntx;

        gpphLibContext->CBInfo.pClientWrNdefCb = NULL;
        gpphLibContext->CBInfo.pClientWrNdefCntx = NULL;
        if(NFCSTATUS_PENDING !=status)
        {
            if (NULL != pClientCb)
            {
                /*Notify to upper layer status and No. of bytes
                actually written */
                pClientCb(pUpperLayerContext, status);          
            }
        }
    }
    return;
}


/**
* Initialize structures needed for the Ndef 
* related operation such as Check Ndef, read, write
* and Ndef foramt.only once allocation 
*/
void phLibNfc_Ndef_Init(void)
{
    if(gpphLibContext->psTransInfo==NULL)
    {
        /*Allocate memory for Transceiveinformation Structure*/
        gpphLibContext->psTransInfo = (phLibNfc_sTransceiveInfo_t *)
            phOsalNfc_GetMemory(sizeof(phLibNfc_sTransceiveInfo_t));
    }
    if(gpphLibContext->psTransInfo==NULL)
    {
        /*exception: Not enough memory*/
        phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,1);
        
    }
    if(NULL == gpphLibContext->ndef_cntx.psNdefMap)
    {
        /*Allocate memory for NDEF Mapping Component Context Structure*/
        gpphLibContext->ndef_cntx.psNdefMap = (phFriNfc_NdefMap_t *)
                    phOsalNfc_GetMemory(sizeof(phFriNfc_NdefMap_t));
    }
    if(NULL != gpphLibContext->ndef_cntx.psNdefMap)
    {
        /*Allocation successful*/
        (void)memset(gpphLibContext->ndef_cntx.psNdefMap,0,sizeof(phFriNfc_NdefMap_t));
        gpphLibContext->ndef_cntx.NdefSendRecvLen = NDEF_SENDRCV_BUF_LEN;
        gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf =
                (uint8_t*) phOsalNfc_GetMemory(gpphLibContext->
                ndef_cntx.NdefSendRecvLen);

        if(NULL != gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf)
        {
            (void)memset(gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf,
                0,
                gpphLibContext->ndef_cntx.NdefSendRecvLen);

            gpphLibContext->psOverHalCtxt =(phFriNfc_OvrHal_t *)
                phOsalNfc_GetMemory(sizeof(phFriNfc_OvrHal_t));
        }
    }
    if(NULL == gpphLibContext->psOverHalCtxt)
    {   /*exception: Not enough memory*/
        phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,1);
    }
    else
    {
        
        (void)memset(gpphLibContext->psOverHalCtxt,0,
            sizeof(phFriNfc_OvrHal_t));
        
        /* Initialize the Overlapped hal structure*/
        gpphLibContext->psOverHalCtxt->psHwReference =
             gpphLibContext->psHwReference;
        if(NULL == gpphLibContext->psDevInputParam )
        {
            gpphLibContext->psDevInputParam = (phHal_sDevInputParam_t *)
                phOsalNfc_GetMemory(sizeof(phHal_sDevInputParam_t));
        }
        gpphLibContext->ndef_cntx.is_ndef = CHK_NDEF_NOT_DONE;      
    }
    if(NULL == gpphLibContext->ndef_cntx.ndef_fmt)
    {
        /*Allocate memory for Ndef format structure*/
        gpphLibContext->ndef_cntx.ndef_fmt = (phFriNfc_sNdefSmtCrdFmt_t *)
                phOsalNfc_GetMemory(sizeof(phFriNfc_sNdefSmtCrdFmt_t));
    }
    if(NULL != gpphLibContext->ndef_cntx.ndef_fmt)
    {
        (void)memset(gpphLibContext->ndef_cntx.ndef_fmt,
                        0,
                        sizeof(phFriNfc_sNdefSmtCrdFmt_t));
    }
    else
    {
        /*exception: Not enough memory*/
        phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,1);
    }
    return;
}
/**
* Free the allocated memory used for Ndef operations 
*/
void phLibNfc_Ndef_DeInit(void)
{
    /* If only allocated then only free the memory*/
    if(gpphLibContext->ndef_cntx.psNdefMap !=NULL)
    {
        if(gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf !=NULL)
        {
            phOsalNfc_FreeMemory(gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf);
            gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf=NULL;
        }
        phOsalNfc_FreeMemory(gpphLibContext->ndef_cntx.psNdefMap);
        gpphLibContext->ndef_cntx.psNdefMap =NULL;
    }

    if(NULL != gpphLibContext->ndef_cntx.ndef_fmt)
    {
        phOsalNfc_FreeMemory(gpphLibContext->ndef_cntx.ndef_fmt);
        gpphLibContext->ndef_cntx.ndef_fmt = NULL;
    }

    if(gpphLibContext->psOverHalCtxt !=NULL)
    {
        phOsalNfc_FreeMemory(gpphLibContext->psOverHalCtxt);
        gpphLibContext->psOverHalCtxt =NULL;
    }
    if(gpphLibContext->psDevInputParam !=NULL)
    {
        phOsalNfc_FreeMemory(gpphLibContext->psDevInputParam);
        gpphLibContext->psDevInputParam = NULL;
    }
    if(gpphLibContext->psTransInfo!=NULL)
    {
        phOsalNfc_FreeMemory(gpphLibContext->psTransInfo);
        gpphLibContext->psTransInfo= NULL;
    }
}


/**
* This function allows  the user to check whether a particular Remote Device
* is NDEF compliant or not
*/
NFCSTATUS phLibNfc_Ndef_CheckNdef(phLibNfc_Handle       hRemoteDevice,
                        pphLibNfc_ChkNdefRspCb_t        pCheckNdef_RspCb,
                        void*                           pContext)
{
    NFCSTATUS RetVal = NFCSTATUS_FAILED;
    
    
    if((NULL == gpphLibContext)|| 
        (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
    {
        /*Lib Nfc not initialized*/
        RetVal = NFCSTATUS_NOT_INITIALISED;
    }
    else if((NULL == pCheckNdef_RspCb)||
        (NULL==pContext)||
        (hRemoteDevice == 0))
    {
        /*parameter sent by upper layer are not valid */
        RetVal= NFCSTATUS_INVALID_PARAMETER;
    }
    else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown)
    {
        RetVal = NFCSTATUS_SHUTDOWN;
    }    
    else if(0 == gpphLibContext->Connected_handle)
    {       
        RetVal=NFCSTATUS_TARGET_NOT_CONNECTED;        
    }
    else if(hRemoteDevice != gpphLibContext->Connected_handle)
    {       
        RetVal=NFCSTATUS_INVALID_HANDLE;        
    }
#ifdef LLCP_TRANSACT_CHANGES
    else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state)
            && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state))
    {
        RetVal= NFCSTATUS_BUSY;
    }
#endif /* #ifdef LLCP_TRANSACT_CHANGES */
    else
    {
        uint8_t     cr_index = 0;
        static uint16_t     data_cnt = 0;
        /* Allocate memory for the ndef related structure */       
        gpphLibContext->ndef_cntx.NdefSendRecvLen=300;
        gpphLibContext->ndef_cntx.eLast_Call = ChkNdef;
        
        /* Resets the component instance */
        RetVal = phFriNfc_NdefMap_Reset( gpphLibContext->ndef_cntx.psNdefMap,
                            gpphLibContext->psOverHalCtxt,
                            (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice,
                            gpphLibContext->psDevInputParam,
                            gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf,
                            gpphLibContext->ndef_cntx.NdefSendRecvLen,
                            gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf,
                            &(gpphLibContext->ndef_cntx.NdefSendRecvLen),
                            &(data_cnt));


        for (cr_index = 0; cr_index < PH_FRINFC_NDEFMAP_CR; cr_index++)
        {
            /* Register the callback for the check ndef */
            RetVal = phFriNfc_NdefMap_SetCompletionRoutine(
                                gpphLibContext->ndef_cntx.psNdefMap,
                                cr_index,
                                phLibNfc_Ndef_CheckNdef_Cb,
                                (void *)gpphLibContext);
        }
        /*call below layer check Ndef function*/
        RetVal = phFriNfc_NdefMap_ChkNdef(gpphLibContext->ndef_cntx.psNdefMap);
        RetVal =PHNFCSTATUS(RetVal);

        if(RetVal== NFCSTATUS_PENDING)
        {
            RetVal = NFCSTATUS_PENDING;
        }        
        else if((RetVal == NFCSTATUS_FAILED) || (RetVal ==(PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
                    NFCSTATUS_INVALID_REMOTE_DEVICE))))
        {
			      RetVal= NFCSTATUS_FAILED;            
        }
        else
        {
            if((0x00 == gpphLibContext->ndef_cntx.Chk_Ndef_Timer_Id)||
              (PH_OSALNFC_INVALID_TIMER_ID == gpphLibContext->ndef_cntx.Chk_Ndef_Timer_Id))
	          {
		            gpphLibContext->ndef_cntx.Chk_Ndef_Timer_Id =
			          phOsalNfc_Timer_Create();      			
	          }	
	          if((0x00 == gpphLibContext->ndef_cntx.Chk_Ndef_Timer_Id)||
              (PH_OSALNFC_INVALID_TIMER_ID == gpphLibContext->ndef_cntx.Chk_Ndef_Timer_Id))
	          {
		            RetVal = NFCSTATUS_FAILED;
	          }
	          else
	          {
	              phOsalNfc_Timer_Start(gpphLibContext->ndef_cntx.Chk_Ndef_Timer_Id,
			          CHK_NDEF_TIMER_TIMEOUT,CheckNdef_timer_cb,NULL);	
                RetVal = NFCSTATUS_PENDING;
	          }            
        }
        if(RetVal== NFCSTATUS_PENDING)
        {
            gpphLibContext->CBInfo.pClientCkNdefCb = pCheckNdef_RspCb;
            gpphLibContext->CBInfo.pClientCkNdefCntx = pContext;
            gpphLibContext->status.GenCb_pending_status=TRUE;
            gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction;
        }
        
    }
    return RetVal;
}

/* Response callback for phLibNfc_Ndef_CheckNdef */
STATIC
void phLibNfc_Ndef_CheckNdef_Cb(void *pContext,NFCSTATUS status)
{
    phLibNfc_ChkNdef_Info_t    Ndef_Info;
    NFCSTATUS RetStatus = NFCSTATUS_SUCCESS;
    pphLibNfc_ChkNdefRspCb_t       pClientCb=NULL;
    phLibNfc_LibContext_t           *pLibNfc_Ctxt = 
                                    (phLibNfc_LibContext_t *)pContext;
    void                    *pUpperLayerContext=NULL;
    phHal_sRemoteDevInformation_t   *ps_rem_dev_info = NULL;                                    

    Ndef_Info.ActualNdefMsgLength = 0;
    Ndef_Info.MaxNdefMsgLength = 0;
    Ndef_Info.NdefCardState = PHLIBNFC_NDEF_CARD_INVALID;
    if(pLibNfc_Ctxt != gpphLibContext)
    {    /*wrong context returned from below layer*/
        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
    }
    else
    {
        ps_rem_dev_info = (phHal_sRemoteDevInformation_t *)
                                    gpphLibContext->Connected_handle;
        if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
        {   /*shutdown called before completion of check Ndef, allow
              shutdown to happen */
            phLibNfc_Pending_Shutdown();
            RetStatus = NFCSTATUS_SHUTDOWN;    
        }
        else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
        {
            RetStatus = NFCSTATUS_ABORTED;          
        }
        else
        {
            if(status == NFCSTATUS_SUCCESS)
            {
                /*Tag is Ndef tag*/
                gpphLibContext->ndef_cntx.is_ndef = TRUE;
                (void)phFriNfc_NdefMap_GetContainerSize(
                                pLibNfc_Ctxt->ndef_cntx.psNdefMap,
                                &(pLibNfc_Ctxt->ndef_cntx.NdefLength),
                                &(pLibNfc_Ctxt->ndef_cntx.NdefActualSize));
                /*Get the data size support by particular ndef card */
                Ndef_Info.ActualNdefMsgLength = pLibNfc_Ctxt->ndef_cntx.NdefActualSize;
                Ndef_Info.MaxNdefMsgLength = pLibNfc_Ctxt->ndef_cntx.NdefLength;
                gpphLibContext->LastTrancvSuccess = TRUE;
                RetStatus =NFCSTATUS_SUCCESS;
            }
            else if (PHNFCSTATUS(status) != NFCSTATUS_MORE_INFORMATION )
            {
                /*Ndef check Failed.Issue a PresenceChk to ascertain if tag is
                  still in the field*/
                RetStatus = phHal4Nfc_PresenceCheck(
                                    gpphLibContext->psHwReference,
                                    phLibNfc_Ndef_ChkNdef_Pchk_Cb,
                                    (void *)gpphLibContext
                                    );
            }             
            else 
            { 
				RetStatus = NFCSTATUS_FAILED; 
                gpphLibContext->LastTrancvSuccess = FALSE;
                gpphLibContext->ndef_cntx.is_ndef = FALSE;
                               
                if ((phHal_eMifare_PICC == ps_rem_dev_info->RemDevType) && 
                    (0x08 == (ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak & 0x08)))
                {

                    /* card type is mifare 1k/4k, then reconnect */
                    RetStatus = phHal4Nfc_Connect(gpphLibContext->psHwReference,  
                                ps_rem_dev_info,
                                (pphHal4Nfc_ConnectCallback_t)
                                phLibNfc_Reconnect_Mifare_Cb,
                                (void *)gpphLibContext);
                }   
                else
                {
                   if((phHal_eJewel_PICC == ps_rem_dev_info->RemDevType)
                       &&(TOPAZ_NDEF_BITMASK & 
                          ps_rem_dev_info->RemoteDevInfo.Jewel_Info.HeaderRom0))
                    {                        
                        gpphLibContext->ndef_cntx.is_ndef = TRUE;
                        RetStatus = phFriNfc_NdefMap_GetContainerSize(
                                        pLibNfc_Ctxt->ndef_cntx.psNdefMap,
                                        &(pLibNfc_Ctxt->ndef_cntx.NdefLength),
                                        &(pLibNfc_Ctxt->ndef_cntx.NdefActualSize));
                        /*Get the data size support by particular ndef card */
                        Ndef_Info.ActualNdefMsgLength = 
                            pLibNfc_Ctxt->ndef_cntx.NdefActualSize;
                        Ndef_Info.MaxNdefMsgLength 
                            = pLibNfc_Ctxt->ndef_cntx.NdefLength
                            = (TOPAZ_LEN_BITMASK & 
                            ps_rem_dev_info->RemoteDevInfo.Jewel_Info.HeaderRom0?
                            TOPAZ_DYNAMIC_LEN:TOPAZ_STATIC_CARD_LEN);   
                        RetStatus = NFCSTATUS_SUCCESS;
                    }
                }                         
            }
            gpphLibContext->LibNfcState.cur_state=eLibNfcHalStateConnect;
        }
        gpphLibContext->status.GenCb_pending_status = FALSE;
        /* Update the current state */
        phLibNfc_UpdateCurState(RetStatus,gpphLibContext);
        if(NFCSTATUS_PENDING != RetStatus)
        {
            if(((ps_rem_dev_info->RemDevType == phHal_eMifare_PICC) 
                && (ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak != 0)&&
               ((NULL == gpphLibContext->psBufferedAuth)
                ||(phHal_eMifareAuthentA == gpphLibContext->psBufferedAuth->cmd.MfCmd)))
               )
            {
                if(NULL != gpphLibContext->psBufferedAuth)
                {
                    if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer)
                    {
                        phOsalNfc_FreeMemory(
                            gpphLibContext->psBufferedAuth->sRecvData.buffer);
                    }
                    if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer)
                    {
                        phOsalNfc_FreeMemory(
                            gpphLibContext->psBufferedAuth->sSendData.buffer);
                    }
                    phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth);
                }
                gpphLibContext->psBufferedAuth
                    =(phLibNfc_sTransceiveInfo_t *) 
                    phOsalNfc_GetMemory(sizeof(phLibNfc_sTransceiveInfo_t));                
                gpphLibContext->psBufferedAuth->addr = 
                (uint8_t)gpphLibContext->ndef_cntx.psNdefMap
                ->StdMifareContainer.currentBlock;
                gpphLibContext->psBufferedAuth->cmd.MfCmd = phHal_eMifareRead16;
                gpphLibContext->psBufferedAuth->sSendData.length
                    = 0;            
                gpphLibContext->psBufferedAuth->sRecvData.length
                    = MIFARE_STD_BLOCK_SIZE;                      
                gpphLibContext->psBufferedAuth->sRecvData.buffer
                    = (uint8_t *)phOsalNfc_GetMemory(MIFARE_STD_BLOCK_SIZE);
                gpphLibContext->psBufferedAuth->sSendData.buffer
                    = (uint8_t *)phOsalNfc_GetMemory(MIFARE_STD_BLOCK_SIZE); 
            }
            pClientCb = gpphLibContext->CBInfo.pClientCkNdefCb;
            pUpperLayerContext = gpphLibContext->CBInfo.pClientCkNdefCntx;
            gpphLibContext->CBInfo.pClientCkNdefCb = NULL;
            gpphLibContext->CBInfo.pClientCkNdefCntx = NULL;
            if(NULL != pClientCb)
            {
                if (!RetStatus)
                {
                    switch (pLibNfc_Ctxt->ndef_cntx.psNdefMap->CardState)
                    {
                        case PH_NDEFMAP_CARD_STATE_INITIALIZED:
                        {
                            Ndef_Info.NdefCardState = 
                                            PHLIBNFC_NDEF_CARD_INITIALISED;
                            break;
                        }

                        case PH_NDEFMAP_CARD_STATE_READ_ONLY:
                        {
                            Ndef_Info.NdefCardState = 
                                            PHLIBNFC_NDEF_CARD_READ_ONLY;
                            break;
                        }

                        case PH_NDEFMAP_CARD_STATE_READ_WRITE:
                        {
                            Ndef_Info.NdefCardState = 
                                            PHLIBNFC_NDEF_CARD_READ_WRITE;
                            break;
                        }

                        default:
                        {
                            Ndef_Info.NdefCardState = 
                                            PHLIBNFC_NDEF_CARD_INVALID;
                            break;
                        }
                    }
                }
                /* call the upper check ndef callback */
                pClientCb(pUpperLayerContext,Ndef_Info,RetStatus);
            }
        }
    }
    return;
}

/*Callback for Presence check call from Chk Ndef*/
STATIC void phLibNfc_Ndef_ChkNdef_Pchk_Cb(void   *pContext,
                                NFCSTATUS  status
                                )
{
    phLibNfc_ChkNdef_Info_t    Ndef_Info = {0,0,0};
    NFCSTATUS RetStatus = NFCSTATUS_SUCCESS;
    pphLibNfc_ChkNdefRspCb_t       pClientCb=NULL;
    phLibNfc_LibContext_t           *pLibNfc_Ctxt = 
                                    (phLibNfc_LibContext_t *)pContext;
    void                    *pUpperLayerContext=NULL;
    phHal_sRemoteDevInformation_t   *ps_rem_dev_info = NULL;  
    if(NFCSTATUS_SUCCESS == status)
    {
        RetStatus = NFCSTATUS_FAILED;
        gpphLibContext->ndef_cntx.is_ndef = FALSE;
    }
    else
    {
        RetStatus = NFCSTATUS_TARGET_LOST;
    }    
    if(pLibNfc_Ctxt != gpphLibContext)
    {    /*wrong context returned from below layer*/
        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
    }
    else
    {
        ps_rem_dev_info = (phHal_sRemoteDevInformation_t *)
                                    gpphLibContext->Connected_handle;
        if(((ps_rem_dev_info->RemDevType == phHal_eMifare_PICC) 
            && (ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak != 0)&&
            ((NULL == gpphLibContext->psBufferedAuth)
            ||(phHal_eMifareAuthentA == gpphLibContext->psBufferedAuth->cmd.MfCmd)))
            )
        {
            if(NULL != gpphLibContext->psBufferedAuth)
            {
                if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer)
                {
                    phOsalNfc_FreeMemory(
                        gpphLibContext->psBufferedAuth->sRecvData.buffer);
                }
                if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer)
                {
                    phOsalNfc_FreeMemory(
                        gpphLibContext->psBufferedAuth->sSendData.buffer);
                }
                phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth);
            }
            gpphLibContext->psBufferedAuth
                =(phLibNfc_sTransceiveInfo_t *) 
                phOsalNfc_GetMemory(sizeof(phLibNfc_sTransceiveInfo_t));                
            gpphLibContext->psBufferedAuth->addr = 
            (uint8_t)gpphLibContext->ndef_cntx.psNdefMap
            ->StdMifareContainer.currentBlock;
            gpphLibContext->psBufferedAuth->cmd.MfCmd = phHal_eMifareRead16;
            gpphLibContext->psBufferedAuth->sSendData.length
                = 0;            
            gpphLibContext->psBufferedAuth->sRecvData.length
                = MIFARE_STD_BLOCK_SIZE;                      
            gpphLibContext->psBufferedAuth->sRecvData.buffer
                = (uint8_t *)phOsalNfc_GetMemory(MIFARE_STD_BLOCK_SIZE);
            gpphLibContext->psBufferedAuth->sSendData.buffer
                = (uint8_t *)phOsalNfc_GetMemory(MIFARE_STD_BLOCK_SIZE); 
        }
        pClientCb = gpphLibContext->CBInfo.pClientCkNdefCb;
        pUpperLayerContext = gpphLibContext->CBInfo.pClientCkNdefCntx;
        gpphLibContext->CBInfo.pClientCkNdefCb = NULL;
        gpphLibContext->CBInfo.pClientCkNdefCntx = NULL;
        if(NULL != pClientCb)
        {
            Ndef_Info.NdefCardState = PHLIBNFC_NDEF_CARD_INVALID;
            /* call the upper check ndef callback */
            pClientCb(pUpperLayerContext,Ndef_Info,RetStatus);
        }
    }
    return;
}
/* Check Ndef Timer Callback*/
STATIC void CheckNdef_timer_cb(uint32_t timer_id, void *pContext)
{
	PHNFC_UNUSED_VARIABLE(pContext);
   phOsalNfc_Timer_Stop(timer_id);
	phOsalNfc_Timer_Delete(gpphLibContext->ndef_cntx.Chk_Ndef_Timer_Id);
	gpphLibContext->ndef_cntx.Chk_Ndef_Timer_Id = 0x00;
	phLibNfc_Ndef_CheckNdef_Cb((void *)gpphLibContext,NFCSTATUS_MORE_INFORMATION);
}

void phLibNfc_Reconnect_Mifare_Cb (
                    void                            *pContext,
                    phHal_sRemoteDevInformation_t   *psRemoteDevInfo,
                    NFCSTATUS                       status)
{
    phLibNfc_ChkNdef_Info_t     Ndef_Info;      
    phLibNfc_LibContext_t       *pLibNfc_Ctxt = 
                                (phLibNfc_LibContext_t *)pContext;
    void                        *pUpperLayerContext = NULL;
    switch(gpphLibContext->ndef_cntx.eLast_Call)
    {
        case ChkNdef:
        {
            pphLibNfc_ChkNdefRspCb_t    pClientCb=NULL;
            pClientCb = pLibNfc_Ctxt->CBInfo.pClientCkNdefCb;
            pUpperLayerContext = pLibNfc_Ctxt->CBInfo.pClientCkNdefCntx;
            pLibNfc_Ctxt->CBInfo.pClientCkNdefCb = NULL;
            pLibNfc_Ctxt->CBInfo.pClientCkNdefCntx = NULL;
            if (NULL != pClientCb)
            {
                status = (NFCSTATUS_SUCCESS == status?
                        NFCSTATUS_FAILED:NFCSTATUS_TARGET_LOST);
                Ndef_Info.ActualNdefMsgLength = 0;
                Ndef_Info.MaxNdefMsgLength = 0;
                /* call the upper check ndef callback */
                pClientCb(pUpperLayerContext,Ndef_Info,status);
            }
        }
        break;
        case NdefRd:
        {
            pphLibNfc_RspCb_t       pClientCb = pLibNfc_Ctxt->CBInfo.pClientRdNdefCb; 
            pUpperLayerContext = pLibNfc_Ctxt->CBInfo.pClientRdNdefCntx;
            pLibNfc_Ctxt->CBInfo.pClientRdNdefCb = NULL;
            pLibNfc_Ctxt->CBInfo.pClientRdNdefCntx = NULL;
            if (NULL != pClientCb)
            {
                status = (NFCSTATUS_SUCCESS == status?
                        NFCSTATUS_FAILED:NFCSTATUS_TARGET_LOST);            
                /* call the upper ndef read callback */
                pClientCb(pUpperLayerContext,status);
            }
        }
        break;
        case NdefWr:
        {
            pphLibNfc_RspCb_t       pClientCb =  pLibNfc_Ctxt->CBInfo.pClientWrNdefCb;        
            pUpperLayerContext = pLibNfc_Ctxt->CBInfo.pClientWrNdefCntx;
            pLibNfc_Ctxt->CBInfo.pClientWrNdefCb = NULL;
            pLibNfc_Ctxt->CBInfo.pClientWrNdefCntx = NULL;
            if (NULL != pClientCb)
            {
                status = (NFCSTATUS_SUCCESS == status?
                        NFCSTATUS_FAILED:NFCSTATUS_TARGET_LOST);              
                /* call the upper ndef write callback */
                pClientCb(pUpperLayerContext,status);
            }
        }
        break;
        case NdefFmt:
#ifdef LIBNFC_READONLY_NDEF
        case NdefReadOnly:
#endif /* #ifdef LIBNFC_READONLY_NDEF */
        {
            pphLibNfc_RspCb_t       pClientCb =
                           pLibNfc_Ctxt->ndef_cntx.pClientNdefFmtCb;  
            pUpperLayerContext= pLibNfc_Ctxt->ndef_cntx.pClientNdefFmtCntx;
            pLibNfc_Ctxt->ndef_cntx.pClientNdefFmtCb = NULL;
            pLibNfc_Ctxt->ndef_cntx.pClientNdefFmtCntx = NULL;
            if (NULL != pClientCb)
            {
                status = (NFCSTATUS_SUCCESS == status?
                        NFCSTATUS_FAILED:NFCSTATUS_TARGET_LOST);            
                /* call the upper ndef format callback */
                pClientCb(pUpperLayerContext,status);
            }
        }
        break;
        case RawTrans:
        {
            phNfc_sData_t trans_resp;           
            pphLibNfc_TransceiveCallback_t pClientCb =
                           pLibNfc_Ctxt->CBInfo.pClientTransceiveCb;
            trans_resp.length = 0;
            pUpperLayerContext = pLibNfc_Ctxt->CBInfo.pClientTranseCntx;
            pLibNfc_Ctxt->CBInfo.pClientTranseCntx= NULL;
            pLibNfc_Ctxt->CBInfo.pClientTransceiveCb= NULL;
            if (NULL != pClientCb)
            {
                status = (NFCSTATUS_SUCCESS == status?
                        NFCSTATUS_FAILED:NFCSTATUS_TARGET_LOST);             
                /* call the upper transceive callback */
                pClientCb(pUpperLayerContext,
                        (uint32_t)psRemoteDevInfo,
                        & trans_resp,
                        status);                
            }
        }
        break;
        default:
        {
        }
        break;
    }
    
}
/**
* Target format to make it NDEF compliant
*/
NFCSTATUS phLibNfc_RemoteDev_FormatNdef(phLibNfc_Handle         hRemoteDevice,
                                        phNfc_sData_t*          pScrtKey,
                                        pphLibNfc_RspCb_t       pNdefformat_RspCb,
                                        void*                   pContext
                                        )
{
    NFCSTATUS RetVal = NFCSTATUS_FAILED;
    
    static uint8_t       mif_std_key[6] ={0},
                         Index = 0;
    if((NULL == gpphLibContext)
        ||(gpphLibContext->LibNfcState.cur_state
                            == eLibNfcHalStateShutdown))
    {
        /*Lib Nfc not initialized*/
        RetVal = NFCSTATUS_NOT_INITIALISED;
    }    
    else if((NULL == pContext) 
        || (NULL == pNdefformat_RspCb)       
        ||(NULL == pScrtKey)
        ||(0 == hRemoteDevice))
    {
        RetVal= NFCSTATUS_INVALID_PARAMETER;
    }
    else if(gpphLibContext->LibNfcState.next_state
                            == eLibNfcHalStateShutdown)
    {
        RetVal= NFCSTATUS_SHUTDOWN;
    }
    else if(0 == gpphLibContext->Connected_handle)
    {       
        RetVal=NFCSTATUS_TARGET_NOT_CONNECTED;        
    }
    else if(hRemoteDevice != gpphLibContext->Connected_handle)
    {       
        RetVal=NFCSTATUS_INVALID_HANDLE;        
    }
    else if((TRUE == gpphLibContext->status.GenCb_pending_status)||
        (NULL != gpphLibContext->ndef_cntx.pClientNdefFmtCb)
        ||(gpphLibContext->ndef_cntx.is_ndef == TRUE))
    {
        /*Previous Callback is Pending*/
        RetVal = NFCSTATUS_REJECTED;
        PHDBG_INFO("LIbNfc:Previous Callback is Pending");
    }
#ifdef LLCP_TRANSACT_CHANGES
    else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state)
            && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state))
    {
        RetVal= NFCSTATUS_BUSY;
    }
#endif /* #ifdef LLCP_TRANSACT_CHANGES */
    else
    {
        uint8_t   fun_id;       
        gpphLibContext->ndef_cntx.eLast_Call = NdefFmt;        
        gpphLibContext->ndef_cntx.NdefSendRecvLen = NDEF_SENDRCV_BUF_LEN;
    
        /* Call ndef format reset, this will initialize the ndef
        format structure, and appropriate values are filled */
        RetVal = phFriNfc_NdefSmtCrd_Reset(gpphLibContext->ndef_cntx.ndef_fmt,
                            gpphLibContext->psOverHalCtxt,
                            (phHal_sRemoteDevInformation_t*)hRemoteDevice,
                            gpphLibContext->psDevInputParam,
                            gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf,
                            &(gpphLibContext->ndef_cntx.NdefSendRecvLen));
        for(fun_id = 0; fun_id < PH_FRINFC_SMTCRDFMT_CR; fun_id++)
        {
            /* Register for all the callbacks */
            RetVal = phFriNfc_NdefSmtCrd_SetCR(gpphLibContext->ndef_cntx.ndef_fmt,
                        fun_id,
                        phLibNfc_Ndef_format_Cb,
                        gpphLibContext);
        }
        /* mif_std_key is required to format the mifare 1k/4k card */
        for (Index =0 ;Index < (pScrtKey->length); Index++ )
        {
            mif_std_key[Index] = *(pScrtKey->buffer++);
        }
        /* Start smart card formatting function   */
        RetVal = phFriNfc_NdefSmtCrd_Format(gpphLibContext->ndef_cntx.ndef_fmt,
                                        mif_std_key);
		RetVal = PHNFCSTATUS(RetVal);
        if(RetVal== NFCSTATUS_PENDING)
        {
            gpphLibContext->ndef_cntx.pClientNdefFmtCb = pNdefformat_RspCb;
            gpphLibContext->ndef_cntx.pClientNdefFmtCntx = pContext;
            gpphLibContext->status.GenCb_pending_status=TRUE;
            gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction;
        }
        else
        {
            RetVal = NFCSTATUS_FAILED;
        }       
    }
    return RetVal;
}

#ifdef LIBNFC_READONLY_NDEF

NFCSTATUS
phLibNfc_ConvertToReadOnlyNdef (
    phLibNfc_Handle         hRemoteDevice,
    pphLibNfc_RspCb_t       pNdefReadOnly_RspCb,
    void*                   pContext
    )
{
    NFCSTATUS           ret_val = NFCSTATUS_FAILED;

    if ((NULL == gpphLibContext)
        || (gpphLibContext->LibNfcState.cur_state
                            == eLibNfcHalStateShutdown))
    {
        /* LibNfc not initialized */
        ret_val = NFCSTATUS_NOT_INITIALISED;
    }
    else if ((NULL == pContext)
        || (NULL == pNdefReadOnly_RspCb)
        || (0 == hRemoteDevice))
    {
        ret_val = NFCSTATUS_INVALID_PARAMETER;
    }
    else if (gpphLibContext->LibNfcState.next_state
            == eLibNfcHalStateShutdown)
    {
        ret_val = NFCSTATUS_SHUTDOWN;
    }
    else if (0 == gpphLibContext->Connected_handle)
    {
        ret_val = NFCSTATUS_TARGET_NOT_CONNECTED;
    }
    else if (hRemoteDevice != gpphLibContext->Connected_handle)
    {
        ret_val = NFCSTATUS_INVALID_HANDLE;
    }
    else if ((TRUE == gpphLibContext->status.GenCb_pending_status)
        || (NULL != gpphLibContext->ndef_cntx.pClientNdefFmtCb)
        || (FALSE == gpphLibContext->ndef_cntx.is_ndef))
    {
        /* Previous Callback is Pending */
        ret_val = NFCSTATUS_REJECTED;
        PHDBG_INFO("LIbNfc:Previous Callback is Pending");
    }
    else if (PH_NDEFMAP_CARD_STATE_READ_WRITE != 
            gpphLibContext->ndef_cntx.psNdefMap->CardState)
    {
        /* Tag is in different state */
        ret_val = NFCSTATUS_REJECTED;
    }
    else
    {
        gpphLibContext->ndef_cntx.eLast_Call = NdefReadOnly;

        if(eLibNfcHalStatePresenceChk != gpphLibContext->LibNfcState.next_state)
        {
            phHal_sRemoteDevInformation_t           *ps_rem_dev_info = 
                                                (phHal_sRemoteDevInformation_t *)hRemoteDevice;
            uint8_t                                 fun_id;

            switch (ps_rem_dev_info->RemDevType)
            {
                case phHal_eMifare_PICC:
                case phHal_eISO14443_A_PICC:
                {
                    if ((phHal_eMifare_PICC == ps_rem_dev_info->RemDevType) 
                        && (0x00 != ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak))
                    {
                        /* Mifare classic 1k/4k not supported */
                        ret_val = NFCSTATUS_REJECTED;
                    }
                    else
                    {   
                        gpphLibContext->ndef_cntx.NdefSendRecvLen = NDEF_SENDRCV_BUF_LEN;

                        /* Call ndef format reset, this will initialize the ndef
                        format structure, and appropriate values are filled */
                        ret_val = phFriNfc_NdefSmtCrd_Reset (gpphLibContext->ndef_cntx.ndef_fmt,
                                                gpphLibContext->psOverHalCtxt,
                                                (phHal_sRemoteDevInformation_t*)hRemoteDevice,
                                                gpphLibContext->psDevInputParam,
                                                gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf,
                                                &(gpphLibContext->ndef_cntx.NdefSendRecvLen));

                        for(fun_id = 0; fun_id < PH_FRINFC_SMTCRDFMT_CR; fun_id++)
                        {
                            /* Register for all the callbacks */
                            ret_val = phFriNfc_NdefSmtCrd_SetCR (gpphLibContext->ndef_cntx.ndef_fmt,
                                                                fun_id, phLibNfc_Ndef_ReadOnly_Cb,
                                                                gpphLibContext);
                        }

                        /* Start smart card formatting function   */
                        ret_val = phFriNfc_NdefSmtCrd_ConvertToReadOnly (
                                                        gpphLibContext->ndef_cntx.ndef_fmt);
                        ret_val = PHNFCSTATUS(ret_val);
                    }
                    break;
                }

                case phHal_eJewel_PICC:
                case phHal_eISO15693_PICC:
                {
// MC: Got the feedback this was #if 0'd because it was resetting the lock bits
// read in check NDEF, and these should not be reset here already.
#if 0
                    static uint16_t     data_cnt = 0;

                    /* Resets the component instance */
                    ret_val = phFriNfc_NdefMap_Reset (gpphLibContext->ndef_cntx.psNdefMap,
                                        gpphLibContext->psOverHalCtxt,
                                        (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice,
                                        gpphLibContext->psDevInputParam,
                                        gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf,
                                        gpphLibContext->ndef_cntx.NdefSendRecvLen,
                                        gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf,
                                        &(gpphLibContext->ndef_cntx.NdefSendRecvLen),
                                        &(data_cnt));
#endif /* #if 0 */


                    for (fun_id = 0; fun_id < PH_FRINFC_NDEFMAP_CR; fun_id++)
                    {
                        /* Register the callback for the check ndef */
                        ret_val = phFriNfc_NdefMap_SetCompletionRoutine (
                                            gpphLibContext->ndef_cntx.psNdefMap,
                                            fun_id, phLibNfc_Ndef_ReadOnly_Cb,
                                            (void *)gpphLibContext);
                    }

                    /* call below layer check Ndef function */
                    ret_val = phFriNfc_NdefMap_ConvertToReadOnly (
                                            gpphLibContext->ndef_cntx.psNdefMap);
                    ret_val = PHNFCSTATUS(ret_val);
                    break;
                }

                default:
                {
                    /* Tag not supported */
                    ret_val = NFCSTATUS_REJECTED;
                    break;
                }
            }            
        }
        else
        {
             gpphLibContext->ndef_cntx.pClientNdefFmtCb= NULL;
             ret_val = NFCSTATUS_PENDING;
        }

        if (NFCSTATUS_PENDING == ret_val)
        {
            gpphLibContext->ndef_cntx.pClientNdefFmtCb = pNdefReadOnly_RspCb;
            gpphLibContext->ndef_cntx.pClientNdefFmtCntx = pContext;

            gpphLibContext->status.GenCb_pending_status = TRUE;
            gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction;
        }
        else
        {
            ret_val = NFCSTATUS_FAILED;
        }
    }
    return ret_val;
}

#endif /* #ifdef LIBNFC_READONLY_NDEF */

/**
* Response callback for NDEF format.
*/
STATIC
void phLibNfc_Ndef_format_Cb(void *Context,NFCSTATUS  status)
{
    NFCSTATUS RetStatus = NFCSTATUS_SUCCESS;
    pphLibNfc_RspCb_t       pClientCb=NULL;
    phLibNfc_LibContext_t   *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)Context;
    void                    *pUpperLayerContext=NULL;
    phHal_sRemoteDevInformation_t   *ps_rem_dev_info = NULL;
    if(pLibNfc_Ctxt != gpphLibContext)
    {   /*wrong context returned*/
        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
    }
    else
    {
        if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
        {
            /*shutdown is pending so issue shutdown*/
            phLibNfc_Pending_Shutdown();
            RetStatus = NFCSTATUS_SHUTDOWN;    
        }
        else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
        {
            RetStatus = NFCSTATUS_ABORTED;          
        }
        else
        {
            gpphLibContext->status.GenCb_pending_status = FALSE;
            if(NFCSTATUS_SUCCESS == status)
            {
                RetStatus = NFCSTATUS_SUCCESS;
            }            
            else if(PHNFCSTATUS(status)==NFCSTATUS_FAILED)
            {
                RetStatus = NFCSTATUS_FAILED;
                ps_rem_dev_info = (phHal_sRemoteDevInformation_t *)
                                    gpphLibContext->Connected_handle;
                if ((phHal_eMifare_PICC == ps_rem_dev_info->RemDevType) && 
                    (0x08 == (ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak & 0x08)))
                {

                    /* card type is mifare 1k/4k, then reconnect */
                    RetStatus = phHal4Nfc_Connect(gpphLibContext->psHwReference,  
                                (phHal_sRemoteDevInformation_t *)
                                gpphLibContext->Connected_handle,
                                (pphHal4Nfc_ConnectCallback_t)
                                phLibNfc_Reconnect_Mifare_Cb,
                                (void *)gpphLibContext);
                }
            }
			else
            {
                /*Target was removed during transaction*/
                RetStatus = NFCSTATUS_FAILED;
            }
            gpphLibContext->LibNfcState.cur_state =eLibNfcHalStateConnect;
        }
        phLibNfc_UpdateCurState(status,gpphLibContext);
        
        pClientCb = gpphLibContext->ndef_cntx.pClientNdefFmtCb;
        pUpperLayerContext= gpphLibContext->ndef_cntx.pClientNdefFmtCntx;
        gpphLibContext->ndef_cntx.pClientNdefFmtCb = NULL;
        gpphLibContext->ndef_cntx.pClientNdefFmtCntx = NULL;
        if(NFCSTATUS_PENDING != RetStatus)
        {
            if (NULL != pClientCb)
            {
                /* Call the tag format upper layer callback */
                pClientCb(pUpperLayerContext,RetStatus);
            }
        }
    }
    return;
}

#ifdef LIBNFC_READONLY_NDEF
STATIC
void
phLibNfc_Ndef_ReadOnly_Cb (
    void        *p_context,
    NFCSTATUS   status)
{
    NFCSTATUS                       ret_status = NFCSTATUS_SUCCESS;
    pphLibNfc_RspCb_t               p_client_cb = NULL;
    phLibNfc_LibContext_t           *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)p_context;
    void                            *p_upper_layer_ctxt = NULL;

    if(pLibNfc_Ctxt != gpphLibContext)
    {
        /*wrong context returned*/
        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
    }
    else
    {
        if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
        {
            /*shutdown is pending so issue shutdown*/
            phLibNfc_Pending_Shutdown();
            ret_status = NFCSTATUS_SHUTDOWN;
        }
        else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
        {
            ret_status = NFCSTATUS_ABORTED;
        }
        else
        {
            gpphLibContext->status.GenCb_pending_status = FALSE;
            if(NFCSTATUS_SUCCESS == status)
            {
                gpphLibContext->ndef_cntx.psNdefMap->CardState = 
                                                PH_NDEFMAP_CARD_STATE_READ_ONLY;
                ret_status = NFCSTATUS_SUCCESS;
            }
            else
            {
                ret_status = NFCSTATUS_FAILED;
            }
            gpphLibContext->LibNfcState.cur_state =eLibNfcHalStateConnect;
        }

        phLibNfc_UpdateCurState(status, gpphLibContext);

        p_client_cb = gpphLibContext->ndef_cntx.pClientNdefFmtCb;
        p_upper_layer_ctxt = gpphLibContext->ndef_cntx.pClientNdefFmtCntx;
        gpphLibContext->ndef_cntx.pClientNdefFmtCb = NULL;
        gpphLibContext->ndef_cntx.pClientNdefFmtCntx = NULL;
        if(NFCSTATUS_PENDING != ret_status)
        {
            if (NULL != p_client_cb)
            {
                /* Call the tag format upper layer callback */
                p_client_cb (p_upper_layer_ctxt, ret_status);
            }
        }
    }
}
#endif /* #ifdef LIBNFC_READONLY_NDEF */

STATIC
void phLibNfc_Ndef_SrchNdefCnt_Cb(void *context, NFCSTATUS status)
{
    static NFCSTATUS RegPrSt=FALSE;
    uint8_t RegStatus=0;
    NFCSTATUS RetVal = NFCSTATUS_SUCCESS ;  
    uint32_t Index=0;   
    
    
	  PHNFC_UNUSED_VARIABLE(context);
    if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
    {   /*shutdown called before completion of Ndef read allow
              shutdown to happen */
        phLibNfc_Pending_Shutdown();
        RetVal = NFCSTATUS_SHUTDOWN;    
    }
    else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
    {
        RetVal = NFCSTATUS_ABORTED;
    }
    else if(NFCSTATUS_SUCCESS != status)
    {
        RetVal = status;
    }
    else
    {
     /* This conditional branch is for QMORE fix */
    }
    gpphLibContext->status.GenCb_pending_status = FALSE;
    
    phLibNfc_UpdateCurState(status,gpphLibContext);
    /* Read is not success send failed to upperlayer Call back*/
    if( RetVal!= NFCSTATUS_SUCCESS ) 
    {
        if((RetVal!=NFCSTATUS_SHUTDOWN)&& (RetVal!=NFCSTATUS_ABORTED))
        {
            RetVal= NFCSTATUS_FAILED;
        }
        gpphLibContext->CBInfo.pClientNdefNtfRespCb(
                            gpphLibContext->CBInfo.pClientNdefNtfRespCntx,
                            NULL,
                            gpphLibContext->Connected_handle,
                            RetVal);
        gpphLibContext->CBInfo.pClientNdefNtfRespCb = NULL;     
        gpphLibContext->CBInfo.pClientNdefNtfRespCntx = NULL;
        return; 
    }

    /*Get the Number of records ( If Raw record parameter is null then API gives number of Records*/
    RetVal = phFriNfc_NdefRecord_GetRecords(
                            gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer,
                            gpphLibContext->phLib_NdefRecCntx.ndef_message.length,
                            NULL,
                            gpphLibContext->phLib_NdefRecCntx.IsChunked,
                            &(gpphLibContext->phLib_NdefRecCntx.NumberOfRawRecords));

    NdefInfo.pNdefMessage = gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer;
    NdefInfo.NdefMessageLengthActual = gpphLibContext->ndef_cntx.NdefActualSize;
    NdefInfo.NdefMessageLengthMaximum = gpphLibContext->ndef_cntx.NdefLength;
    NdefInfo.NdefRecordCount =0;

    /*Allocate memory to hold the records Read*/
    NdefInfo.pNdefRecord = phOsalNfc_GetMemory
        (sizeof(phFriNfc_NdefRecord_t)* gpphLibContext->phLib_NdefRecCntx.NumberOfRawRecords );  
    if(NULL==NdefInfo.pNdefRecord)
    {
        gpphLibContext->CBInfo.pClientNdefNtfRespCb(
                            gpphLibContext->CBInfo.pClientNdefNtfRespCntx,
                            NULL,
                            gpphLibContext->Connected_handle,
                            NFCSTATUS_FAILED);
        gpphLibContext->CBInfo.pClientNdefNtfRespCb = NULL;     
        gpphLibContext->CBInfo.pClientNdefNtfRespCntx = NULL;
        return;     
    }

    pNdefRecord=NdefInfo.pNdefRecord;   
    /*If phLibNfc_Ndef_SearchNdefContent Reg type is NULL return all the Records*/
    if(gpphLibContext->ndef_cntx.pNdef_NtfSrch_Type==NULL)
    {
        RetVal = phFriNfc_NdefRecord_GetRecords(
                        gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer,
                        gpphLibContext->phLib_NdefRecCntx.ndef_message.length,
                        gpphLibContext->phLib_NdefRecCntx.RawRecords,
                        gpphLibContext->phLib_NdefRecCntx.IsChunked,
                        &(gpphLibContext->phLib_NdefRecCntx.NumberOfRawRecords));

        for (Index = 0; Index < gpphLibContext->phLib_NdefRecCntx.NumberOfRawRecords; Index++)
        {
            RetVal = phFriNfc_NdefRecord_Parse( 
                        pNdefRecord,
                        gpphLibContext->phLib_NdefRecCntx.RawRecords[Index]);
            pNdefRecord++;
            NdefInfo.NdefRecordCount++;
        }
    }
    else
    {
        
        /* Look for registerd TNF */
        RetVal = phFriNfc_NdefReg_DispatchPacket( 
                    &(gpphLibContext->phLib_NdefRecCntx.NdefReg),
                    gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer,
                    (uint16_t)gpphLibContext->phLib_NdefRecCntx.ndef_message.length);
        if(NFCSTATUS_SUCCESS != RetVal)
        {
            /*phFriNfc_NdefReg_DispatchPacket is failed call upper layer*/
            gpphLibContext->CBInfo.pClientNdefNtfRespCb(gpphLibContext->CBInfo.pClientNdefNtfRespCntx,
                                                    NULL,gpphLibContext->Connected_handle,NFCSTATUS_FAILED);
            gpphLibContext->CBInfo.pClientNdefNtfRespCb = NULL;     
            gpphLibContext->CBInfo.pClientNdefNtfRespCntx = NULL;
            return; 
        }

        while(1 != RegStatus)
        {
            /* Process the NDEF records, If match FOUND we will get Call back*/
            RegStatus = phFriNfc_NdefReg_Process(   &(gpphLibContext->phLib_NdefRecCntx.NdefReg),
                                                &RegPrSt);
            if(RegPrSt == TRUE)
            {
                /*  Processing Done */
                break;
            }
            /*If match found the CbParam will be updated by lower layer, copy the record info*/
            for(Index=0;Index<gpphLibContext->phLib_NdefRecCntx.CbParam.Count;Index++)
            {
                pNdefRecord->Tnf  = gpphLibContext->phLib_NdefRecCntx.CbParam.Records[Index].Tnf;
                pNdefRecord->TypeLength  = 
                    gpphLibContext->phLib_NdefRecCntx.CbParam.Records[Index].TypeLength;
                pNdefRecord->PayloadLength  = 
                    gpphLibContext->phLib_NdefRecCntx.CbParam.Records[Index].PayloadLength;
                pNdefRecord->IdLength  = 
                    gpphLibContext->phLib_NdefRecCntx.CbParam.Records[Index].IdLength;
                pNdefRecord->Flags = 
                    gpphLibContext->phLib_NdefRecCntx.CbParam.Records[Index].Flags;

                pNdefRecord->Id = phOsalNfc_GetMemory(pNdefRecord->IdLength);
                pNdefRecord->Type = phOsalNfc_GetMemory(pNdefRecord->TypeLength);
                pNdefRecord->PayloadData = phOsalNfc_GetMemory(pNdefRecord->PayloadLength);         
                
                (void)memcpy(pNdefRecord->Id,
                    gpphLibContext->phLib_NdefRecCntx.CbParam.Records[Index].Id,
                    pNdefRecord->IdLength);
                (void)memcpy(pNdefRecord->PayloadData,
                    gpphLibContext->phLib_NdefRecCntx.CbParam.Records[Index].PayloadData,
                    pNdefRecord->PayloadLength);
                (void)memcpy(pNdefRecord->Type,
                    gpphLibContext->phLib_NdefRecCntx.CbParam.Records[Index].Type,
                    pNdefRecord->TypeLength);

                pNdefRecord++;
                NdefInfo.NdefRecordCount++;
            }
        }
    }
    /* If no record found call upper layer with failed status*/
    if(pNdefRecord == NdefInfo.pNdefRecord)
    {
        NdefInfo.NdefRecordCount =0;
        gpphLibContext->CBInfo.pClientNdefNtfRespCb(
                    gpphLibContext->CBInfo.pClientNdefNtfRespCntx,
                    &NdefInfo,gpphLibContext->Connected_handle,
                    NFCSTATUS_SUCCESS);
    
    }
    else
    {
        /*Call upperlayer Call back with match records*/

        gpphLibContext->CBInfo.pClientNdefNtfRespCb(
                    gpphLibContext->CBInfo.pClientNdefNtfRespCntx,
                    &NdefInfo,gpphLibContext->Connected_handle,
                    NFCSTATUS_SUCCESS);
        /*Remove entry from FRI*/
        RetVal = phFriNfc_NdefReg_RmCb( 
                    &(gpphLibContext->phLib_NdefRecCntx.NdefReg),
                    gpphLibContext->phLib_NdefRecCntx.NdefCb );
        /*Free the memory*/
        if(gpphLibContext->ndef_cntx.pNdef_NtfSrch_Type!=NULL)
        {
            pNdefRecord=NdefInfo.pNdefRecord;
            for(Index=0;Index<gpphLibContext->phLib_NdefRecCntx.CbParam.Count;Index++)
            {
                phOsalNfc_FreeMemory(pNdefRecord->Id);
                phOsalNfc_FreeMemory(pNdefRecord->PayloadData);
                phOsalNfc_FreeMemory(pNdefRecord->Type);
                pNdefRecord++;
            }
        }
    }

    gpphLibContext->CBInfo.pClientNdefNtfRespCb = NULL;     
    gpphLibContext->CBInfo.pClientNdefNtfRespCntx = NULL;
    
}

STATIC
void phLibNfc_Ndef_Rtd_Cb( void *CallBackParam)
{
    /*There will be single call back given to all match
      It's processed in phLibNfc_Ndef_SrchNdefCnt_Cb*/  
    PHNFC_UNUSED_VARIABLE(CallBackParam);
}

NFCSTATUS phLibNfc_Ndef_SearchNdefContent(  
                                phLibNfc_Handle                 hRemoteDevice,
                                phLibNfc_Ndef_SrchType_t*       psSrchTypeList,  
                                uint8_t                         uNoSrchRecords,
                                pphLibNfc_Ndef_Search_RspCb_t   pNdefNtfRspCb,  
                                void *                          pContext   
                                )
{

     NFCSTATUS  RetVal =NFCSTATUS_SUCCESS;
     uint32_t Index=0;
     uint8_t     cr_index = 0;


      if((NULL == gpphLibContext) ||
        (gpphLibContext->LibNfcState.cur_state
                            == eLibNfcHalStateShutdown))
      {
         RetVal = NFCSTATUS_NOT_INITIALISED;
      }
     /* Check the state for DeInit is called or not,if yes return NFCSTATUS_SHUTDOWN*/
      else if(gpphLibContext->LibNfcState.next_state
                            == eLibNfcHalStateShutdown)
     {       
        RetVal= NFCSTATUS_SHUTDOWN;
     }
     else if( (NULL == pNdefNtfRspCb) ||
        (NULL == pContext ) ||
        (0 == hRemoteDevice))
     {
        RetVal= NFCSTATUS_INVALID_PARAMETER;        
     } 
     else if( (NULL != psSrchTypeList) && (0==uNoSrchRecords))
     {
        RetVal= NFCSTATUS_INVALID_PARAMETER;        
     }
     else if(0 == gpphLibContext->Connected_handle)
     {   /*presently no target or tag is connected*/ 
        RetVal=NFCSTATUS_TARGET_NOT_CONNECTED;        
     }
     else if(hRemoteDevice != gpphLibContext->Connected_handle)
     {   /*This handle of the device sent by application is not connected */ 
        RetVal=NFCSTATUS_INVALID_HANDLE;        
     }  
     else if((TRUE == gpphLibContext->status.GenCb_pending_status)       
        ||(NULL!=gpphLibContext->CBInfo.pClientNdefNtfRespCb))
     {
        /*Previous callback is pending*/
        RetVal = NFCSTATUS_REJECTED;
     }
     else
     {
        gpphLibContext->ndef_cntx.pNdef_NtfSrch_Type = psSrchTypeList;

        if(psSrchTypeList!=NULL)
        {
            /*Maximum records supported*/
            gpphLibContext->phLib_NdefRecCntx.NumberOfRecords = 255;
            /*Reset the FRI component to add the Reg type*/
            RetVal = phFriNfc_NdefReg_Reset( 
                            &(gpphLibContext->phLib_NdefRecCntx.NdefReg),
                            gpphLibContext->phLib_NdefRecCntx.NdefTypes_array,
                            &(gpphLibContext->phLib_NdefRecCntx.RecordsExtracted),
                            &(gpphLibContext->phLib_NdefRecCntx.CbParam),
                            gpphLibContext->phLib_NdefRecCntx.ChunkedRecordsarray,  
                            gpphLibContext->phLib_NdefRecCntx.NumberOfRecords);

            gpphLibContext->phLib_NdefRecCntx.NdefCb = phOsalNfc_GetMemory(sizeof(phFriNfc_NdefReg_Cb_t));
            if(gpphLibContext->phLib_NdefRecCntx.NdefCb==NULL)
            {
                /*exception: Not enough memory*/
                phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,1);
            }
            gpphLibContext->phLib_NdefRecCntx.NdefCb->NdefCallback = phLibNfc_Ndef_Rtd_Cb;
            /*Copy the TNF types to search in global structure*/    
            gpphLibContext->phLib_NdefRecCntx.NdefCb->NumberOfRTDs = uNoSrchRecords;
            for(Index=0;Index<uNoSrchRecords;Index++)
            {
                gpphLibContext->phLib_NdefRecCntx.NdefCb->NdefType[Index] = psSrchTypeList->Type;
                gpphLibContext->phLib_NdefRecCntx.NdefCb->Tnf[Index] = psSrchTypeList->Tnf ; 
                gpphLibContext->phLib_NdefRecCntx.NdefCb->NdeftypeLength[Index] = psSrchTypeList->TypeLength;
                psSrchTypeList++;
            }
            /* Add the TNF type to FRI component*/

            RetVal = phFriNfc_NdefReg_AddCb(&(gpphLibContext->phLib_NdefRecCntx.NdefReg),
                                                gpphLibContext->phLib_NdefRecCntx.NdefCb );

        }
        gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer = 
            phOsalNfc_GetMemory(gpphLibContext->ndef_cntx.NdefActualSize);
        gpphLibContext->phLib_NdefRecCntx.ndef_message.length = 
            gpphLibContext->ndef_cntx.NdefActualSize;
        /*Set Complete routine for NDEF Read*/
        for (cr_index = 0; cr_index < PH_FRINFC_NDEFMAP_CR; cr_index++)
        {
            RetVal= phFriNfc_NdefMap_SetCompletionRoutine(
                                gpphLibContext->ndef_cntx.psNdefMap,
                                cr_index,
                                phLibNfc_Ndef_SrchNdefCnt_Cb,
                                (void *)gpphLibContext);

        }
        gpphLibContext->ndef_cntx.NdefContinueRead = PH_FRINFC_NDEFMAP_SEEK_BEGIN;
        /* call below layer Ndef Read*/
        RetVal = phFriNfc_NdefMap_RdNdef(gpphLibContext->ndef_cntx.psNdefMap,
                        gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer,
                        (uint32_t*)&gpphLibContext->phLib_NdefRecCntx.ndef_message.length,
                        PH_FRINFC_NDEFMAP_SEEK_BEGIN);

        if(NFCSTATUS_PENDING == RetVal)
        {
            gpphLibContext->CBInfo.pClientNdefNtfRespCb = pNdefNtfRspCb;        
            gpphLibContext->CBInfo.pClientNdefNtfRespCntx = pContext;
            gpphLibContext->status.GenCb_pending_status=TRUE;
            gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction;
        }
        else if (NFCSTATUS_SUCCESS == RetVal)
        {
            RetVal= NFCSTATUS_SUCCESS;
        }
        else
        {
            /*Ndef read failed*/
            RetVal = NFCSTATUS_FAILED;
        }
    }
    return RetVal;

}

