/*
 * 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>
#include <phFriNfc_MifareStdMap.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)) ||
                    (0x01 == ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak))
                {

                    /* 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,
                        (phLibNfc_Handle)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,
    phNfc_sData_t*          pScrtKey,
    pphLibNfc_RspCb_t       pNdefReadOnly_RspCb,
    void*                   pContext
    )
{
    NFCSTATUS           ret_val = NFCSTATUS_FAILED;
    static uint8_t      mif_std_key[6] ={0},
                        Index = 0;

    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
    {
        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))
                    {
                        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);
                        }

                        /* Start mifare NFC read only function   */
                        /* mif_std_key is required to format the mifare 1k/4k card */
                        if(pScrtKey != NULL && pScrtKey->length == MIFARE_STD_KEY_LEN)
                        {
                            for (Index =0 ;Index < (pScrtKey->length); Index++ )
                            {
                                mif_std_key[Index] = *(pScrtKey->buffer++);
                            }

                            ret_val = phFriNfc_MifareStdMap_ConvertToReadOnly (
                                      gpphLibContext->ndef_cntx.psNdefMap, mif_std_key);
                            ret_val = PHNFCSTATUS(ret_val);
                        }
                    }
                    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;

}

