/*
* 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.c
* Project: NFC FRI / HALDL
*
* $Date: Tue Jun 1 14:53:48 2010 $
* $Author: ing07385 $
* $Revision: 1.89 $
* $Aliases: NFC_FRI1.1_WK1024_SDK $
*
*/
/*
************************* Header Files ****************************************
*/
#define LOG_TAG "NFC"
#include <phLibNfc.h>
#include <phDal4Nfc.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 <phNfcStatus.h>
#include <cutils/log.h>
/*
*************************** Macro's ******************************************
*/
extern int dlopen_firmware();
#ifndef STATIC_DISABLE
#define STATIC static
#else
#define STATIC
#endif
/*
*************************** Global Variables **********************************
*/
pphLibNfc_LibContext_t gpphLibContext=NULL;
/*
*************************** Static Function Declaration ***********************
*/
/* Init callback */
STATIC void phLibNfc_InitCb(void *pContext,NFCSTATUS status);
/* Shutdown callback */
STATIC void phLibNfc_ShutdownCb(void *pContext,NFCSTATUS status);
/**Default notification handler registered with lower layer immediately after
successful initialization*/
STATIC void phLibNfc_DefaultHandler(
void *context,
phHal_eNotificationType_t type,
phHal4Nfc_NotificationInfo_t info,
NFCSTATUS status
);
/*
*************************** Function Definitions ******************************
*/
NFCSTATUS phLibNfc_Mgt_ConfigureDriver (pphLibNfc_sConfig_t psConfig,
void ** ppDriverHandle)
{
if(NULL != gpphLibContext)
{
return NFCSTATUS_ALREADY_INITIALISED;
}
return phDal4Nfc_Config(psConfig, ppDriverHandle);
}
NFCSTATUS phLibNfc_Mgt_UnConfigureDriver (void * pDriverHandle)
{
if(NULL != gpphLibContext)
{
return NFCSTATUS_ALREADY_INITIALISED;
}
return phDal4Nfc_ConfigRelease(pDriverHandle);
}
NFCSTATUS phLibNfc_HW_Reset ()
{
NFCSTATUS Status = NFCSTATUS_SUCCESS;
Status = phDal4Nfc_Reset(1);
Status = phDal4Nfc_Reset(0);
Status = phDal4Nfc_Reset(1);
return Status;
}
NFCSTATUS phLibNfc_Download_Mode ()
{
return phDal4Nfc_Download();
}
int phLibNfc_Load_Firmware_Image ()
{
int status;
status = dlopen_firmware();
return status;
}
// Function for delay the recovery in case wired mode is set
// to complete the possible pending transaction with SE
void phLibNfc_Mgt_Recovery ()
{
/* Wait before recovery if wired mode */
if (gpphLibContext->sSeContext.eActivatedMode == phLibNfc_SE_ActModeWired)
{
usleep (12000000);
}
return;
}
extern uint8_t nxp_nfc_isoxchg_timeout;
NFCSTATUS phLibNfc_SetIsoXchgTimeout(uint8_t timeout) {
nxp_nfc_isoxchg_timeout = timeout;
return NFCSTATUS_SUCCESS;
}
int phLibNfc_GetIsoXchgTimeout() {
return nxp_nfc_isoxchg_timeout;
}
extern uint32_t nxp_nfc_hci_response_timeout;
NFCSTATUS phLibNfc_SetHciTimeout(uint32_t timeout_in_ms) {
nxp_nfc_hci_response_timeout = timeout_in_ms;
return NFCSTATUS_SUCCESS;
}
int phLibNfc_GetHciTimeout() {
return nxp_nfc_hci_response_timeout;
}
extern uint8_t nxp_nfc_felica_timeout;
NFCSTATUS phLibNfc_SetFelicaTimeout(uint8_t timeout_in_ms) {
nxp_nfc_felica_timeout = timeout_in_ms;
return NFCSTATUS_SUCCESS;
}
int phLibNfc_GetFelicaTimeout() {
return nxp_nfc_felica_timeout;
}
extern uint8_t nxp_nfc_mifareraw_timeout;
NFCSTATUS phLibNfc_SetMifareRawTimeout(uint8_t timeout) {
nxp_nfc_mifareraw_timeout = timeout;
return NFCSTATUS_SUCCESS;
}
int phLibNfc_GetMifareRawTimeout() {
return nxp_nfc_mifareraw_timeout;
}
/**
* Initialize the phLibNfc interface.
*/
NFCSTATUS phLibNfc_Mgt_Initialize(void *pDriverHandle,
pphLibNfc_RspCb_t pInitCb,
void *pContext)
{
NFCSTATUS Status = NFCSTATUS_SUCCESS;
if((NULL == pDriverHandle)||(NULL == pInitCb))
{
Status = NFCSTATUS_INVALID_PARAMETER;
}
else if(NULL == gpphLibContext)
{
/* Initialize the Lib context */
gpphLibContext=(pphLibNfc_LibContext_t)phOsalNfc_GetMemory(
(uint32_t)sizeof(phLibNfc_LibContext_t));
if(NULL == gpphLibContext)
{
Status=NFCSTATUS_INSUFFICIENT_RESOURCES;
}
else
{
(void)memset((void *)gpphLibContext,0,(
(uint32_t)sizeof(phLibNfc_LibContext_t)));
/* Store the Callback and context in LibContext structure*/
gpphLibContext->CBInfo.pClientInitCb=pInitCb;
gpphLibContext->CBInfo.pClientInitCntx=pContext;
/* Initialize the HwReferece structure */
gpphLibContext->psHwReference=(phHal_sHwReference_t *)
phOsalNfc_GetMemory((uint32_t)sizeof(phHal_sHwReference_t));
(void)memset((void *)gpphLibContext->psHwReference,0,
((uint32_t)sizeof(phHal_sHwReference_t)));
/* Allocate the Memory for the Transceive info */
if( gpphLibContext->psHwReference!=NULL)
{
gpphLibContext->psHwReference->p_board_driver = pDriverHandle;
Status = phLibNfc_UpdateNextState(gpphLibContext,
eLibNfcHalStateInitandIdle);
if(Status==NFCSTATUS_SUCCESS)
{
Status=phHal4Nfc_Open(
gpphLibContext->psHwReference,
eInitDefault,
phLibNfc_InitCb,
(void *)gpphLibContext);
}
}
else
{
Status = NFCSTATUS_INSUFFICIENT_RESOURCES;
}
phLibNfc_Ndef_Init();
}
}
else if(gpphLibContext->LibNfcState.next_state==eLibNfcHalStateShutdown)
{
Status = NFCSTATUS_SHUTDOWN;
}
else
{
Status=NFCSTATUS_ALREADY_INITIALISED;
}
return Status;
}
/*
* This function called by the HAL4 when the initialization seq is completed.
*/
STATIC void phLibNfc_InitCb(void *pContext,NFCSTATUS status)
{
pphLibNfc_LibContext_t pLibContext=NULL;
pphLibNfc_RspCb_t pClientCb=NULL;
void *pUpperLayerContext=NULL;
/* Initialize the local variable */
pLibContext = (pphLibNfc_LibContext_t)pContext;
pClientCb =pLibContext->CBInfo.pClientInitCb;
pUpperLayerContext=pLibContext->CBInfo.pClientInitCntx;
if(status == NFCSTATUS_SUCCESS)
{
/* Get the Lib context */
pLibContext=(pphLibNfc_LibContext_t)gpphLibContext;
gpphLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeOff;
if(pLibContext->psHwReference->uicc_connected==TRUE)
{
/* populate state of the secured element */
gpphLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeDefault;
sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_CurrentState=phLibNfc_SE_Active;
pLibContext->sSeContext.uUiccActivate=TRUE;
}
if(pLibContext->psHwReference->smx_connected==TRUE)
{
/* populate state of the secured element */
gpphLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeDefault;
sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_CurrentState=phLibNfc_SE_Inactive;
pLibContext->sSeContext.uSmxActivate =FALSE;
}
phLibNfc_UpdateCurState(status,pLibContext);
(void)phHal4Nfc_RegisterNotification(
pLibContext->psHwReference,
eRegisterDefault,
phLibNfc_DefaultHandler,
(void*)pLibContext
);
/* call the upper layer register function */
(*pClientCb)(pUpperLayerContext,status);
}
else
{
/*Change the status code failed*/
status = NFCSTATUS_FAILED;
/* Get the Lib context */
pLibContext=(pphLibNfc_LibContext_t)gpphLibContext;
phLibNfc_UpdateCurState(status,pLibContext);
/* Allocate the Memory for the Transceive info */
if(pLibContext->psHwReference!= NULL)
{
phOsalNfc_FreeMemory(pLibContext->psHwReference);
pLibContext->psHwReference = NULL;
}
(*pClientCb)(pUpperLayerContext, status);
phOsalNfc_FreeMemory(pLibContext);
pLibContext= NULL;
gpphLibContext = NULL;
}
return;
}
/**Default notification handler registered with lower layer immediately after
successful initialization*/
STATIC void phLibNfc_DefaultHandler(
void *context,
phHal_eNotificationType_t type,
phHal4Nfc_NotificationInfo_t info,
NFCSTATUS status
)
{
if(context != (void *)gpphLibContext)
{
phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
}
else
{
info = info;
if((NFC_EVENT_NOTIFICATION == type) &&
(NFCSTATUS_BOARD_COMMUNICATION_ERROR == status))
{
phLibNfc_UpdateCurState(NFCSTATUS_FAILED,gpphLibContext);
phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1);
}
}
return;
}
/**
* De-Initialize the LIB NFC.
*/
NFCSTATUS phLibNfc_Mgt_DeInitialize(void * pDriverHandle,
pphLibNfc_RspCb_t pDeInitCb,
void* pContext
)
{
NFCSTATUS Status = NFCSTATUS_SUCCESS;
pphLibNfc_LibContext_t pLibContext = gpphLibContext;
if(NULL==pDriverHandle)
{
/*Check for valid parameters */
Status = NFCSTATUS_INVALID_PARAMETER;
}
else if((pLibContext==NULL)
|| (pLibContext->LibNfcState.cur_state
== eLibNfcHalStateShutdown))
{ /*Lib Nfc not initlized*/
Status = NFCSTATUS_NOT_INITIALISED;
}
else
{
if(pDeInitCb==NULL)
{
phHal4Nfc_Hal4Reset(pLibContext->psHwReference,(void *)pLibContext);
if(pLibContext->psHwReference!=NULL)
{
phOsalNfc_FreeMemory(pLibContext->psHwReference);
pLibContext->psHwReference = NULL;
}
/*Free the memory allocated during NDEF read,write
and NDEF formatting*/
phLibNfc_Ndef_DeInit();
phOsalNfc_FreeMemory(pLibContext);
gpphLibContext=NULL;
pLibContext= NULL;
}
else
{
if (NULL!= pLibContext->CBInfo.pClientShutdownCb)
{
/* Previous callback pending */
Status = NFCSTATUS_BUSY;
}
Status = NFCSTATUS_PENDING;
if(TRUE != pLibContext->status.GenCb_pending_status)
{
Status = phHal4Nfc_Close(pLibContext->psHwReference,
phLibNfc_ShutdownCb,
(void *)pLibContext);
}
if(Status== NFCSTATUS_PENDING)
{
pLibContext->CBInfo.pClientShutdownCb = pDeInitCb;
pLibContext->CBInfo.pClientShtdwnCntx = pContext;
pLibContext->status.GenCb_pending_status=TRUE;
pLibContext->LibNfcState.next_state= eLibNfcHalStateShutdown;
}
else
{
Status =NFCSTATUS_FAILED;
}
}
}
return Status;
}
/* shutdown callback -
Free the allocated memory here */
STATIC void phLibNfc_ShutdownCb(void *pContext,NFCSTATUS status)
{
pphLibNfc_RspCb_t pClientCb=NULL;
void *pUpperLayerContext=NULL;
pphLibNfc_LibContext_t pLibContext=NULL;
PHNFC_UNUSED_VARIABLE(pContext);
/* Get the Lib context */
pLibContext=(pphLibNfc_LibContext_t)gpphLibContext;
if(pLibContext == NULL)
{
status = NFCSTATUS_FAILED;
}
else
{
/* Initialize the local variable */
pClientCb =pLibContext->CBInfo.pClientShutdownCb;
pUpperLayerContext=pLibContext->CBInfo.pClientShtdwnCntx;
if(status == NFCSTATUS_SUCCESS)
{
pLibContext->LibNfcState.cur_state = eLibNfcHalStateShutdown;
phLibNfc_UpdateCurState(status,pLibContext);
pLibContext->status.GenCb_pending_status=FALSE;
/* Allocate the Memory for the Transceive info */
if(pClientCb!=NULL)
{
(*pClientCb)(pUpperLayerContext, status);
}
if(pLibContext->psHwReference!=NULL)
{
phOsalNfc_FreeMemory(pLibContext->psHwReference);
pLibContext->psHwReference = NULL;
}
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 = NULL;
}
/*Free the memory allocated during NDEF read,write
and NDEF formatting*/
phLibNfc_Ndef_DeInit();
phOsalNfc_FreeMemory(pLibContext);
gpphLibContext=NULL;
pLibContext= NULL;
}
else
{
/* shutdown sequence failed by HAL 4 */
status= NFCSTATUS_FAILED;
pLibContext=(pphLibNfc_LibContext_t)gpphLibContext;
phLibNfc_UpdateCurState(status,pLibContext);
pLibContext->status.GenCb_pending_status=FALSE;
if(pClientCb!=NULL)
{
(*pClientCb)(pUpperLayerContext,status);
}
}
}
}
/**
* Pending shutdown call.
*/
void phLibNfc_Pending_Shutdown(void)
{
NFCSTATUS RetStatus = NFCSTATUS_SUCCESS ;
gpphLibContext->status.GenCb_pending_status = FALSE;
RetStatus = phHal4Nfc_Close(
gpphLibContext->psHwReference,
phLibNfc_ShutdownCb,
(void *)gpphLibContext);
PHNFC_UNUSED_VARIABLE(RetStatus);
return;
}
/**
* Reset the LIB NFC.
*/
NFCSTATUS phLibNfc_Mgt_Reset(void *pContext)
{
NFCSTATUS Status = NFCSTATUS_SUCCESS;
phLibNfc_LibContext_t *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)pContext;
if((pLibNfc_Ctxt == NULL)
|| (gpphLibContext->LibNfcState.cur_state
== eLibNfcHalStateShutdown))
{ /*Lib Nfc not initlized*/
Status = NFCSTATUS_NOT_INITIALISED;
}
else if(NULL == pContext)
{
Status = NFCSTATUS_INVALID_PARAMETER;
}
/* Check for valid state,If De initialize is called then
return NFCSTATUS_SHUTDOWN */
else if(gpphLibContext->LibNfcState.next_state
== eLibNfcHalStateShutdown)
{
Status = NFCSTATUS_SHUTDOWN;
}
else
{
/*Reset all callback status*/
(void) memset(&(gpphLibContext->RegNtfType),0,
sizeof(phLibNfc_Registry_Info_t));
(void) memset(&(gpphLibContext->sADDconfig),0,
sizeof(phLibNfc_sADD_Cfg_t));
(void) memset(&(gpphLibContext->ndef_cntx),0,
sizeof(phLibNfc_NdefInfo_t));
(void) memset(&(gpphLibContext->sNfcIp_Context),0,
sizeof(phLibNfc_NfcIpInfo_t));
(void) memset(&(gpphLibContext->sCardEmulCfg),0,
sizeof(phHal_sEmulationCfg_t));
(void) memset(&(gpphLibContext->Discov_handle),0,
MAX_REMOTE_DEVICES);
/*Free memory allocated for NDEF records*/
if(NULL != gpphLibContext->psBufferedAuth)
{
if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer)
{
phOsalNfc_FreeMemory(
gpphLibContext->psBufferedAuth->sRecvData.buffer);
gpphLibContext->psBufferedAuth->sRecvData.buffer = NULL;
}
if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer)
{
phOsalNfc_FreeMemory(
gpphLibContext->psBufferedAuth->sSendData.buffer);
gpphLibContext->psBufferedAuth->sSendData.buffer = NULL;
}
phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth);
gpphLibContext->psBufferedAuth = NULL;
}
if(NULL != gpphLibContext->psTransInfo)
{
phOsalNfc_FreeMemory(gpphLibContext->psTransInfo);
gpphLibContext->psTransInfo = NULL;
}
if(NULL != gpphLibContext->ndef_cntx.psNdefMap)
{
if(NULL != gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf)
{
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->psOverHalCtxt)
{
phOsalNfc_FreeMemory(gpphLibContext->psOverHalCtxt);
gpphLibContext->psTransInfo = NULL;
}
if(NULL != gpphLibContext->psDevInputParam)
{
phOsalNfc_FreeMemory(gpphLibContext->psDevInputParam);
gpphLibContext->psDevInputParam = NULL;
}
if(NULL != gpphLibContext->ndef_cntx.ndef_fmt)
{
phOsalNfc_FreeMemory(gpphLibContext->ndef_cntx.ndef_fmt);
gpphLibContext->ndef_cntx.ndef_fmt = NULL;
}
if(NULL != pNdefRecord)
{
if(NULL != pNdefRecord->Id)
{
phOsalNfc_FreeMemory(pNdefRecord->Id);
pNdefRecord->Id = NULL;
}
if(NULL != pNdefRecord->Type)
{
phOsalNfc_FreeMemory(pNdefRecord->Type);
pNdefRecord->Type = NULL;
}
if(NULL != pNdefRecord->PayloadData)
{
phOsalNfc_FreeMemory(pNdefRecord->PayloadData);
pNdefRecord->PayloadData = NULL;
}
}
if(NULL != NdefInfo.pNdefRecord)
{
phOsalNfc_FreeMemory(NdefInfo.pNdefRecord);
NdefInfo.pNdefRecord = NULL;
}
if(NULL != gpphLibContext->phLib_NdefRecCntx.NdefCb)
{
phOsalNfc_FreeMemory(gpphLibContext->phLib_NdefRecCntx.NdefCb);
gpphLibContext->phLib_NdefRecCntx.NdefCb = NULL;
}
if(NULL != gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer)
{
phOsalNfc_FreeMemory(gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer);
gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer = NULL;
}
/* No device is connected */
gpphLibContext->Connected_handle = 0x00;
gpphLibContext->Prev_Connected_handle = 0x00;
gpphLibContext->ReleaseType = NFC_INVALID_RELEASE_TYPE;
gpphLibContext->eLibNfcCfgMode = NFC_DISCOVERY_STOP;
/*Lib Nfc Stack is initilized and in idle state*/
gpphLibContext->LibNfcState.cur_state = eLibNfcHalStateInitandIdle;
/* Reset all callback status */
gpphLibContext->CBInfo.pClientCkNdefCb = NULL;
gpphLibContext->CBInfo.pClientCkNdefCntx = NULL;
gpphLibContext->CBInfo.pClientConCntx = NULL;
gpphLibContext->CBInfo.pClientConnectCb = NULL;
gpphLibContext->CBInfo.pClientDConCntx = NULL;
gpphLibContext->CBInfo.pClientDisCfgCntx = NULL;
gpphLibContext->CBInfo.pClientDisConfigCb = NULL;
gpphLibContext->CBInfo.pClientInitCb = NULL;
gpphLibContext->CBInfo.pClientInitCntx = gpphLibContext;
gpphLibContext->CBInfo.pClientNdefNtfRespCb = NULL;
gpphLibContext->CBInfo.pClientNdefNtfRespCntx = NULL;
gpphLibContext->CBInfo.pClientNtfRegRespCB = NULL;
gpphLibContext->CBInfo.pClientNtfRegRespCntx = NULL;
gpphLibContext->CBInfo.pClientPresChkCb = NULL;
gpphLibContext->CBInfo.pClientPresChkCntx = NULL;
gpphLibContext->CBInfo.pClientRdNdefCb = NULL;
gpphLibContext->CBInfo.pClientRdNdefCntx = NULL;
gpphLibContext->CBInfo.pClientShtdwnCntx = NULL;
gpphLibContext->CBInfo.pClientShutdownCb = NULL;
gpphLibContext->CBInfo.pClientTransceiveCb = NULL;
gpphLibContext->CBInfo.pClientTranseCntx = NULL;
gpphLibContext->CBInfo.pClientWrNdefCb = NULL;
gpphLibContext->CBInfo.pClientWrNdefCntx = NULL;
gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb = NULL;
gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx = NULL;
gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb = NULL;
gpphLibContext->sNfcIp_Context.pClientNfcIpRxCntx = NULL;
gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb = NULL;
gpphLibContext->sNfcIp_Context.pClientNfcIpTxCntx = NULL;
gpphLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb = NULL;
gpphLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt = NULL;
gpphLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCb = NULL;
gpphLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCtxt = NULL;
/*No callback is pending*/
gpphLibContext->status.GenCb_pending_status = FALSE;
}
return Status;
}
/**
* LibNfc state machine next state update.
*/
NFCSTATUS
phLibNfc_UpdateNextState(
pphLibNfc_LibContext_t pLibContext,
phLibNfc_State_t next_state
)
{
NFCSTATUS status = NFCSTATUS_INVALID_STATE;
switch(pLibContext->LibNfcState.cur_state)
{
case eLibNfcHalStateShutdown:
{
switch(next_state)
{
case eLibNfcHalStateShutdown:
case eLibNfcHalStateInitandIdle:
status = NFCSTATUS_SUCCESS;
break;
default:
break;
}
}
break;
case eLibNfcHalStateConfigReady:
{
switch(next_state)
{
case eLibNfcHalStateShutdown:
case eLibNfcHalStateConfigReady:
case eLibNfcHalStateInitandIdle:
case eLibNfcHalStateConnect:
status = NFCSTATUS_SUCCESS;
break;
default:
break;
}
}
break;
case eLibNfcHalStateConnect:
{
switch(next_state)
{
case eLibNfcHalStateShutdown:
case eLibNfcHalStateRelease:
case eLibNfcHalStateTransaction:
case eLibNfcHalStatePresenceChk:
status = NFCSTATUS_SUCCESS;
break;
default:
break;
}
}
break;
case eLibNfcHalStatePresenceChk:
{
switch(next_state)
{
case eLibNfcHalStateShutdown:
case eLibNfcHalStateConfigReady:
case eLibNfcHalStateRelease:
case eLibNfcHalStateTransaction:
case eLibNfcHalStatePresenceChk:
status = NFCSTATUS_SUCCESS;
break;
default:
break;
}
}
break;
case eLibNfcHalStateInitandIdle:
{
switch(next_state)
{
case eLibNfcHalStateShutdown:
case eLibNfcHalStateConfigReady:
status = NFCSTATUS_SUCCESS;
break;
default:
break;
}
}
break;
default:
break;
}
pLibContext->LibNfcState.next_state =
(uint8_t)((NFCSTATUS_SUCCESS == status)?next_state:pLibContext->LibNfcState.next_state);
return status;
}
/**
* LibNfc state machine current state update.
*/
void
phLibNfc_UpdateCurState(
NFCSTATUS status,
pphLibNfc_LibContext_t psLibContext
)
{
switch(psLibContext->LibNfcState.next_state)
{
case eLibNfcHalStateTransaction:
psLibContext->LibNfcState.cur_state = (uint8_t)eLibNfcHalStateConnect;
break;
case eLibNfcHalStateRelease:
psLibContext->LibNfcState.cur_state
= (uint8_t)(psLibContext->status.DiscEnbl_status == TRUE?
eLibNfcHalStateInitandIdle:eLibNfcHalStateConfigReady);
break;
case eLibNfcHalStateInvalid:
break;
default:
psLibContext->LibNfcState.cur_state
= (uint8_t)((NFCSTATUS_SUCCESS == status)?
psLibContext->LibNfcState.next_state:
psLibContext->LibNfcState.cur_state);
}
psLibContext->LibNfcState.next_state = (uint8_t)eLibNfcHalStateInvalid;
return;
}
/* Interface to stack capabilities */
NFCSTATUS phLibNfc_Mgt_GetstackCapabilities(
phLibNfc_StackCapabilities_t *phLibNfc_StackCapabilities,
void *pContext)
{
NFCSTATUS RetVal = NFCSTATUS_FAILED;
/*Check Lib Nfc stack is initilized*/
if((NULL == gpphLibContext)||
(gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
{
RetVal = NFCSTATUS_NOT_INITIALISED;
}
/*Check application has sent the valid parameters*/
else if((NULL == phLibNfc_StackCapabilities)
|| (NULL == pContext))
{
RetVal= NFCSTATUS_INVALID_PARAMETER;
}
else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown)
{
RetVal = NFCSTATUS_SHUTDOWN;
}
else if(TRUE == gpphLibContext->status.GenCb_pending_status)
{
/*Previous operation is pending */
RetVal = NFCSTATUS_BUSY;
}
else
{
/* Tag Format Capabilities*/
phLibNfc_StackCapabilities->psFormatCapabilities.Desfire = TRUE;
phLibNfc_StackCapabilities->psFormatCapabilities.MifareStd = TRUE;
phLibNfc_StackCapabilities->psFormatCapabilities.MifareUL = TRUE;
phLibNfc_StackCapabilities->psFormatCapabilities.FeliCa = FALSE;
phLibNfc_StackCapabilities->psFormatCapabilities.Jewel = FALSE;
phLibNfc_StackCapabilities->psFormatCapabilities.ISO14443_4A = FALSE;
phLibNfc_StackCapabilities->psFormatCapabilities.ISO14443_4B = FALSE;
phLibNfc_StackCapabilities->psFormatCapabilities.MifareULC = TRUE;
phLibNfc_StackCapabilities->psFormatCapabilities.ISO15693 = FALSE;
/* Tag Mapping Capabilities */
phLibNfc_StackCapabilities->psMappingCapabilities.FeliCa = TRUE;
phLibNfc_StackCapabilities->psMappingCapabilities.Desfire = TRUE;
phLibNfc_StackCapabilities->psMappingCapabilities.ISO14443_4A = TRUE;
phLibNfc_StackCapabilities->psMappingCapabilities.ISO14443_4B = TRUE;
phLibNfc_StackCapabilities->psMappingCapabilities.MifareStd = TRUE;
phLibNfc_StackCapabilities->psMappingCapabilities.MifareUL = TRUE;
phLibNfc_StackCapabilities->psMappingCapabilities.MifareULC = TRUE;
phLibNfc_StackCapabilities->psMappingCapabilities.Jewel = TRUE;
phLibNfc_StackCapabilities->psMappingCapabilities.ISO15693 = FALSE;
/*Call Hal4 Get Dev Capabilities to get info about protocols supported
by Lib Nfc*/
PHDBG_INFO("LibNfc:Get Stack capabilities ");
RetVal= phHal4Nfc_GetDeviceCapabilities(
gpphLibContext->psHwReference,
&(phLibNfc_StackCapabilities->psDevCapabilities),
(void *)gpphLibContext);
LIB_NFC_VERSION_SET(phLibNfc_StackCapabilities->psDevCapabilities.hal_version,
PH_HAL4NFC_VERSION,
PH_HAL4NFC_REVISION,
PH_HAL4NFC_PATCH,
PH_HAL4NFC_BUILD);
phLibNfc_StackCapabilities->psDevCapabilities.fw_version=
gpphLibContext->psHwReference->device_info.fw_version;
phLibNfc_StackCapabilities->psDevCapabilities.hci_version=
gpphLibContext->psHwReference->device_info.hci_version;
phLibNfc_StackCapabilities->psDevCapabilities.hw_version=
gpphLibContext->psHwReference->device_info.hw_version;
phLibNfc_StackCapabilities->psDevCapabilities.model_id=
gpphLibContext->psHwReference->device_info.model_id;
(void)memcpy(phLibNfc_StackCapabilities->psDevCapabilities.full_version,
gpphLibContext->psHwReference->device_info.full_version,NXP_FULL_VERSION_LEN);
/* Check the firmware version */
if (nxp_nfc_full_version == NULL) {
// Couldn't load firmware, just pretend we're up to date.
ALOGW("Firmware image not available: this device might be running old NFC firmware!");
phLibNfc_StackCapabilities->psDevCapabilities.firmware_update_info = 0;
} else {
phLibNfc_StackCapabilities->psDevCapabilities.firmware_update_info = memcmp(phLibNfc_StackCapabilities->psDevCapabilities.full_version, nxp_nfc_full_version,
NXP_FULL_VERSION_LEN);
}
if(NFCSTATUS_SUCCESS != RetVal)
{
RetVal = NFCSTATUS_FAILED;
}
}
return RetVal;
}
NFCSTATUS phLibNfc_Mgt_ConfigureTestMode(void *pDriverHandle,
pphLibNfc_RspCb_t pTestModeCb,
phLibNfc_Cfg_Testmode_t eTstmode,
void *pContext)
{
NFCSTATUS Status = NFCSTATUS_SUCCESS;
phHal4Nfc_InitType_t eInitType=eInitDefault;
if((NULL == pDriverHandle)||(NULL == pTestModeCb))
{
Status = NFCSTATUS_INVALID_PARAMETER;
}
else if((NULL != gpphLibContext) && \
(gpphLibContext->LibNfcState.next_state==eLibNfcHalStateShutdown))
{
Status = NFCSTATUS_SHUTDOWN;
}
else if( (eTstmode == phLibNfc_TstMode_On) && (NULL != gpphLibContext))
{
Status=NFCSTATUS_ALREADY_INITIALISED;
}
else if( (eTstmode == phLibNfc_TstMode_Off) && (NULL == gpphLibContext))
{
Status = NFCSTATUS_NOT_INITIALISED;
}
else if( (eTstmode == phLibNfc_TstMode_Off) && (NULL != gpphLibContext))
{
if (NULL!= gpphLibContext->CBInfo.pClientShutdownCb)
{ /* Previous callback pending */
Status = NFCSTATUS_BUSY;
}
else
{
Status = NFCSTATUS_PENDING;
if(TRUE != gpphLibContext->status.GenCb_pending_status)
{
Status = phHal4Nfc_Close(gpphLibContext->psHwReference,
phLibNfc_ShutdownCb,
(void *)gpphLibContext);
}
if(Status== NFCSTATUS_PENDING)
{
gpphLibContext->CBInfo.pClientShutdownCb = pTestModeCb;
gpphLibContext->CBInfo.pClientShtdwnCntx = pContext;
gpphLibContext->status.GenCb_pending_status=TRUE;
gpphLibContext->LibNfcState.next_state= eLibNfcHalStateShutdown;
}
else
{
Status =NFCSTATUS_FAILED;
}
}
}
else
{
/* Initialize the Lib context */
gpphLibContext=(pphLibNfc_LibContext_t)phOsalNfc_GetMemory(
(uint32_t)sizeof(phLibNfc_LibContext_t));
if(NULL == gpphLibContext)
{
Status=NFCSTATUS_INSUFFICIENT_RESOURCES;
}
else
{
(void)memset((void *)gpphLibContext,0,(
(uint32_t)sizeof(phLibNfc_LibContext_t)));
/* Store the Callback and context in LibContext structure*/
gpphLibContext->CBInfo.pClientInitCb=pTestModeCb;
gpphLibContext->CBInfo.pClientInitCntx=pContext;
/* Initialize the HwReferece structure */
gpphLibContext->psHwReference=(phHal_sHwReference_t *)
phOsalNfc_GetMemory((uint32_t)sizeof(phHal_sHwReference_t));
(void)memset((void *)gpphLibContext->psHwReference,0,
((uint32_t)sizeof(phHal_sHwReference_t)));
/* Allocate the Memory for the Transceive info */
if( gpphLibContext->psHwReference!=NULL)
{
gpphLibContext->psHwReference->p_board_driver = pDriverHandle;
Status = phLibNfc_UpdateNextState(gpphLibContext,
eLibNfcHalStateInitandIdle);
if(Status==NFCSTATUS_SUCCESS)
{
if(eTstmode == phLibNfc_TstMode_On)
eInitType = eInitTestModeOn;
if(eTstmode == phLibNfc_TstMode_Off)
eInitType = eInitDefault;
Status=phHal4Nfc_Open(
gpphLibContext->psHwReference,
eInitType,
phLibNfc_InitCb,
(void *)gpphLibContext);
}
}
else
{
Status = NFCSTATUS_INSUFFICIENT_RESOURCES;
}
phLibNfc_Ndef_Init();
}
}
return Status;
}