blob: 31dbbac54da5f8400726579a93dd0dc5ee0a6bda [file] [log] [blame]
/*
* 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,
(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,
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;
}