/*
* 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 phHal4Nfc.c
* \brief Hal4Nfc source.
*
* Project: NFC-FRI 1.1
*
* $Date: Fri Jun 11 09:32:23 2010 $
* $Author: ing07385 $
* $Revision: 1.192 $
* $Aliases: NFC_FRI1.1_WK1023_R35_1 $
*
*/
/* ---------------------------Include files ---------------------------------*/
#include <phHal4Nfc.h>
#include <phHal4Nfc_Internal.h>
#include <phOsalNfc.h>
#include <phHciNfc.h>
#include <phLlcNfc.h>
#include <phDal4Nfc.h>
#include <phDnldNfc.h>
#include <phOsalNfc_Timer.h>
/* ------------------------------- Macros -----------------------------------*/
#ifndef HAL_UNIT_TEST
#define STATIC static
#else
#define STATIC
#endif/*#ifndef UNIT_TEST*/
#define HAL4_LAYERS 3
#define LAYER_HCI 2
#define LAYER_LLC 1
#define LAYER_DAL 0
/* --------------------Structures and enumerations --------------------------*/
phHal_sHwReference_t *gpphHal4Nfc_Hwref;
static void phHal4Nfc_IoctlComplete(
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,
void *pInfo
);
static void phHal4Nfc_LowerNotificationHandler(
void *pContext,
void *pHwRef,
uint8_t type,
void *pInfo
);
static void phHal4Nfc_HandleEvent(
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,
void *pInfo
);
static void phHal4Nfc_OpenComplete(
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,
void *pInfo
);
static void phHal4Nfc_CloseComplete(
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,
void *pInfo
);
static void phHal4Nfc_DownloadComplete(
void *pContext,
void *pHwRef,
uint8_t type,
void *pInfo
);
static NFCSTATUS phHal4Nfc_Configure_Layers(
phNfcLayer_sCfg_t **pphLayer
);
/*Callback for Self tests*/
static void phHal4Nfc_SelfTestComplete(
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,
void *pInfo
);
/**
* The open callback function to be called by the HCI when open (initializaion)
* sequence is completed or if there is an error in initialization.
* It is passed as a parameter to HCI when calling HCI Init.
*/
static void phHal4Nfc_OpenComplete(
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,
void *pInfo
)
{
NFCSTATUS status = ((phNfc_sCompletionInfo_t *)pInfo)->status;
pphHal4Nfc_GenCallback_t pUpper_OpenCb
= Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb;
void *pUpper_Context
= Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
if(status == NFCSTATUS_SUCCESS)
{
PHDBG_INFO("Hal4:Open Successful");
#ifdef MERGE_SAK_SW1 /*Software Workaround*/
if(eHal4StateOpenAndReady == Hal4Ctxt->Hal4NextState)
{
status = phHciNfc_System_Configure (
Hal4Ctxt->psHciHandle,
(void *)gpphHal4Nfc_Hwref,
PH_HAL4NFC_TGT_MERGE_ADDRESS,
PH_HAL4NFC_TGT_MERGE_SAK /*config value*/
);
}
if(NFCSTATUS_PENDING != status)
#endif/*#ifdef MERGE_SAK_SW1*/
{
/*Update State*/
Hal4Ctxt->Hal4CurrentState = Hal4Ctxt->Hal4NextState;
Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb = NULL;
if(NULL != pUpper_OpenCb)
{
/*Upper layer's Open Cb*/
(*pUpper_OpenCb)(Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
NFCSTATUS_SUCCESS
);
}
}
}
else/*Open did not succeed.Go back to reset state*/
{
Hal4Ctxt->Hal4CurrentState = eHal4StateClosed;
Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
Hal4Ctxt->psHciHandle = NULL;
phOsalNfc_FreeMemory((void *)Hal4Ctxt->pHal4Nfc_LayerCfg);
Hal4Ctxt->pHal4Nfc_LayerCfg = NULL;
phOsalNfc_FreeMemory((void *)Hal4Ctxt);
gpphHal4Nfc_Hwref->hal_context = NULL;
gpphHal4Nfc_Hwref = NULL;
PHDBG_INFO("Hal4:Open Failed");
/*Call upper layer's Open Cb with error status*/
if(NULL != pUpper_OpenCb)
{
/*Upper layer's Open Cb*/
(*pUpper_OpenCb)(pUpper_Context,status);
}
}
return;
}
/**
* The close callback function called by the HCI when close sequence is
* completed or if there is an error in closing.
* It is passed as a parameter to HCI when calling HCI Release.
*/
static void phHal4Nfc_CloseComplete(
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,
void *pInfo
)
{
NFCSTATUS status= ((phNfc_sCompletionInfo_t *)pInfo)->status;
pphHal4Nfc_GenCallback_t pUpper_CloseCb;
void *pUpper_Context;
uint8_t RemoteDevNumber = 0;
pUpper_CloseCb = Hal4Ctxt->sUpperLayerInfo.pUpperCloseCb;
pUpper_Context = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
/*Update state*/
Hal4Ctxt->Hal4CurrentState = Hal4Ctxt->Hal4NextState;
Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
/*If Closed successfully*/
if(NFCSTATUS_SUCCESS == status)
{
Hal4Ctxt->psHciHandle = NULL;
/*Free all heap allocations*/
phOsalNfc_FreeMemory((void *)Hal4Ctxt->pHal4Nfc_LayerCfg);
Hal4Ctxt->pHal4Nfc_LayerCfg = NULL;
/*Free ADD context info*/
if(NULL != Hal4Ctxt->psADDCtxtInfo)
{
while(RemoteDevNumber < MAX_REMOTE_DEVICES)
{
if(NULL != Hal4Ctxt->rem_dev_list[RemoteDevNumber])
{
phOsalNfc_FreeMemory((void *)
(Hal4Ctxt->rem_dev_list[RemoteDevNumber]));
Hal4Ctxt->rem_dev_list[RemoteDevNumber] = NULL;
}
RemoteDevNumber++;
}
Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
phOsalNfc_FreeMemory(Hal4Ctxt->psADDCtxtInfo);
}/*if(NULL != Hal4Ctxt->psADDCtxtInfo)*/
/*Free Trcv context info*/
if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
{
if(NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer)
{
phOsalNfc_FreeMemory(
Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer
);
}
if((NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
&& (NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData))
{
phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData);
}
phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo);
}/*if(NULL != Hal4Ctxt->psTrcvCtxtInfo)*/
/*Free Hal context and Hardware reference*/
gpphHal4Nfc_Hwref->hal_context = NULL;
gpphHal4Nfc_Hwref = NULL;
phOsalNfc_FreeMemory((void *)Hal4Ctxt);
}/* if(NFCSTATUS_SUCCESS == status)*/
/*Call Upper layer's Close Cb with status*/
(*pUpper_CloseCb)(pUpper_Context,status);
return;
}
/*
* For configuring the various layers during the Initialization call
*
*
*/
static
NFCSTATUS
phHal4Nfc_Configure_Layers(
phNfcLayer_sCfg_t **pphLayer
)
{
uint8_t index = HAL4_LAYERS - 1;
uint8_t i = 0;
NFCSTATUS status = NFCSTATUS_SUCCESS ;
PHDBG_INFO("Hal4:Configuring layers");
*pphLayer = (phNfcLayer_sCfg_t *) phOsalNfc_GetMemory(
sizeof(phNfcLayer_sCfg_t) * HAL4_LAYERS);
if( NULL == *pphLayer)
{
status = PHNFCSTVAL(CID_NFC_HAL,
NFCSTATUS_INSUFFICIENT_RESOURCES);/*Memory allocation error*/
}
else
{
(void)memset((void *)*pphLayer,0,(
sizeof(phNfcLayer_sCfg_t) * HAL4_LAYERS));
for(i=0 ; i < HAL4_LAYERS ;i++, index-- )
{
(*pphLayer + i)->layer_index = index;
switch(index)
{
case LAYER_HCI: /*Configure Hci*/
{
(*pphLayer+i)->layer_name =(uint8_t *) "Hci";
(*pphLayer+i)->layer_registry = NULL;
(*pphLayer+i)->layer_next =
(((phNfcLayer_sCfg_t *)*pphLayer) + i + 1);
break;
}
case LAYER_LLC:/*Configure LLC*/
{
(*pphLayer+i)->layer_registry = phLlcNfc_Register;
(*pphLayer+i)->layer_name = (uint8_t *)"Llc";
(*pphLayer+i)->layer_next =
(((phNfcLayer_sCfg_t *)*pphLayer) + i + 1);
break;
}
case LAYER_DAL: /*Configure the DAL*/
{
(*pphLayer+i)->layer_registry = phDal4Nfc_Register;
(*pphLayer+i)->layer_name = (uint8_t *)"Dal";
(*pphLayer+i)->layer_next = NULL ;
break;
}
default:
break;
} /* End of Switch */
} /* End of For Loop */
} /* End of NULL Check */
return status ;
}
#ifdef ANDROID
#define LOG_TAG "NFC-HCI"
#include <utils/Log.h>
#include <dlfcn.h>
#define FW_PATH "/system/vendor/firmware/libpn544_fw.so"
const unsigned char *nxp_nfc_full_version = NULL;
const unsigned char *nxp_nfc_fw = NULL;
int dlopen_firmware() {
void *p;
void *handle = dlopen(FW_PATH, RTLD_NOW);
if (handle == NULL) {
ALOGE("Could not open %s", FW_PATH);
return -1;
}
p = dlsym(handle, "nxp_nfc_full_version");
if (p == NULL) {
ALOGE("Could not link nxp_nfc_full_version");
return -1;
}
nxp_nfc_full_version = (unsigned char *)p;
p = dlsym(handle, "nxp_nfc_fw");
if (p == NULL) {
ALOGE("Could not link nxp_nfc_fw");
return -1;
}
nxp_nfc_fw = (unsigned char *)p;
return 0;
}
#endif
/**
* The open function called by the upper HAL when HAL4 is to be opened
* (initialized).
*
*/
NFCSTATUS phHal4Nfc_Open(
phHal_sHwReference_t *psHwReference,
phHal4Nfc_InitType_t InitType,
pphHal4Nfc_GenCallback_t pOpenCallback,
void *pContext
)
{
NFCSTATUS openRetVal = NFCSTATUS_SUCCESS;
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
phHciNfc_Init_t eHciInitType = (phHciNfc_Init_t)InitType;
/*Set Default Clock settings once*/
static phHal_sHwConfig_t sHwConfig = {
{0},
NXP_DEFAULT_CLK_REQUEST,
NXP_DEFAULT_INPUT_CLK
};
/*NULL checks*/
if(NULL == psHwReference || NULL == pOpenCallback)
{
phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
openRetVal = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
}
else if(NULL != gpphHal4Nfc_Hwref)
{
/*Hal4 context is open or open in progress ,return Ctxt already open*/
openRetVal = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_ALREADY_INITIALISED);
}
else/*Do an initialization*/
{
#ifdef ANDROID
dlopen_firmware();
#endif
/*If hal4 ctxt in Hwreference is NULL create a new context*/
if(NULL == ((phHal_sHwReference_t *)psHwReference)->hal_context)
{
Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)
phOsalNfc_GetMemory((uint32_t)sizeof(
phHal4Nfc_Hal4Ctxt_t)
);
((phHal_sHwReference_t *)psHwReference)->hal_context = Hal4Ctxt;
}
else/*Take context from Hw reference*/
{
Hal4Ctxt = ((phHal_sHwReference_t *)psHwReference)->hal_context;
}
if(NULL == Hal4Ctxt)
{
openRetVal = PHNFCSTVAL(CID_NFC_HAL,
NFCSTATUS_INSUFFICIENT_RESOURCES);
}
else
{
(void)memset((void *)Hal4Ctxt,
0,
((uint32_t)sizeof(phHal4Nfc_Hal4Ctxt_t)));
/* Configure layers if not configured */
if( NULL == Hal4Ctxt->pHal4Nfc_LayerCfg )
{
openRetVal = phHal4Nfc_Configure_Layers(
&(Hal4Ctxt->pHal4Nfc_LayerCfg)
);
}
if( openRetVal == NFCSTATUS_SUCCESS )
{
/*update Next state*/
Hal4Ctxt->Hal4NextState = (HCI_NFC_DEVICE_TEST == eHciInitType?
eHal4StateSelfTestMode:eHal4StateOpenAndReady);
/*Store callback and context ,and set Default settings in Context*/
Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb = pOpenCallback;
Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
Hal4Ctxt->sTgtConnectInfo.EmulationState = NFC_EVT_DEACTIVATED;
gpphHal4Nfc_Hwref = psHwReference;
PHDBG_INFO("Hal4:Calling Hci-Init");
openRetVal = phHciNfc_Initialise (
(void *)&Hal4Ctxt->psHciHandle,
psHwReference,
eHciInitType,
&sHwConfig,
(pphNfcIF_Notification_CB_t)
phHal4Nfc_LowerNotificationHandler,
(void *)Hal4Ctxt,
Hal4Ctxt->pHal4Nfc_LayerCfg
);
/*Hci Init did not succeed.free Resources and return*/
if( (openRetVal != NFCSTATUS_SUCCESS)
&& (PHNFCSTATUS (openRetVal) != NFCSTATUS_PENDING) )
{
phOsalNfc_FreeMemory(Hal4Ctxt->pHal4Nfc_LayerCfg);
phOsalNfc_FreeMemory(Hal4Ctxt);
Hal4Ctxt = NULL;
}
}/*if( openRetVal == NFCSTATUS_SUCCESS )*/
else/*Free the context*/
{
phOsalNfc_FreeMemory(Hal4Ctxt);
}/*else*/
}
}
return openRetVal;
}
/** The I/O Control function allows the caller to use (vendor-) specific
* functionality provided by the lower layer or by the hardware. */
NFCSTATUS phHal4Nfc_Ioctl(
phHal_sHwReference_t *psHwReference,
uint32_t IoctlCode,
phNfc_sData_t *pInParam,
phNfc_sData_t *pOutParam,
pphHal4Nfc_IoctlCallback_t pIoctlCallback,
void *pContext
)
{
NFCSTATUS RetStatus = NFCSTATUS_FAILED;
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
uint32_t config_type = 0;
uint8_t ind = 0;
/*NULL checks*/
if((NULL == psHwReference)
|| (NULL == pIoctlCallback)
)
{
phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
}
/*Only the Ioctls NFC_FW_DOWNLOAD_CHECK and NFC_FW_DOWNLOAD are allowed in
the uninitialized state of HAL*/
else if(NULL == psHwReference->hal_context)
{
#ifdef FW_DOWNLOAD
#if !defined (NXP_FW_INTEGRITY_VERIFY)
if(NFC_FW_DOWNLOAD_CHECK == IoctlCode)
{
RetStatus = phDnldNfc_Run_Check(
psHwReference
);
}
else
#endif /* !defined (NXP_FW_INTEGRITY_VERIFY) */
if((NFC_FW_DOWNLOAD == IoctlCode)
&&(NULL == gpphHal4Nfc_Hwref))/*Indicates current state is shutdown*/
{
Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)
phOsalNfc_GetMemory((uint32_t)sizeof(
phHal4Nfc_Hal4Ctxt_t)
);
if(NULL == Hal4Ctxt)
{
RetStatus = PHNFCSTVAL(CID_NFC_HAL,
NFCSTATUS_INSUFFICIENT_RESOURCES);
}
else
{
((phHal_sHwReference_t *)psHwReference)->hal_context
= Hal4Ctxt;
(void)memset((void *)Hal4Ctxt,
0,
((uint32_t)sizeof(phHal4Nfc_Hal4Ctxt_t)));
Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb
= pIoctlCallback;/*Register upper layer callback*/
Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam = pOutParam;
/*Upgrade the firmware*/
RetStatus = phDnldNfc_Upgrade (
psHwReference,
phHal4Nfc_DownloadComplete,
Hal4Ctxt
);
if((NFCSTATUS_SUCCESS == RetStatus)
|| (NFCSTATUS_PENDING != PHNFCSTATUS(RetStatus))
)
{
phOsalNfc_FreeMemory(Hal4Ctxt);
((phHal_sHwReference_t *)psHwReference)->hal_context = NULL;
}
}
}
else
#endif/*NFC_FW_DOWNLOAD*/
{
RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED);
}
}
else/*Status is Initialised*/
{
/*Register upper layer context*/
Hal4Ctxt = psHwReference->hal_context;
Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam = pOutParam;
switch(IoctlCode)
{
/*Self test Ioctls*/
case DEVMGMT_ANTENNA_TEST:
case DEVMGMT_SWP_TEST:
case DEVMGMT_NFCWI_TEST:
if(eHal4StateSelfTestMode ==Hal4Ctxt->Hal4CurrentState)
{
RetStatus = phHciNfc_System_Test(
Hal4Ctxt->psHciHandle,
(void *)psHwReference,
IoctlCode ,
pInParam
);
}
break;
/*PRBS Test*/
case DEVMGMT_PRBS_TEST:
RetStatus = phHciNfc_PRBS_Test(
Hal4Ctxt->psHciHandle,
(void *)psHwReference,
IoctlCode ,
pInParam
);
break;
/*To Set Antenna Power Level*/
case NFC_ANTENNA_CWG:
if(eHal4StateSelfTestMode ==Hal4Ctxt->Hal4CurrentState)
{
RetStatus = phHciNfc_System_Configure (
Hal4Ctxt->psHciHandle,
(void *)psHwReference,
NFC_ANTENNA_CWG,
pInParam->buffer[0] /**Set Power Level*/
);
}
break;
/*Not allowed when Init is complete*/
case NFC_FW_DOWNLOAD_CHECK:
case NFC_FW_DOWNLOAD:
RetStatus = PHNFCSTVAL(CID_NFC_HAL,
NFCSTATUS_BUSY);
break;
/*Gpio read*/
case NFC_GPIO_READ:
/* if(eHal4StateSelfTestMode == Hal4Ctxt->Hal4CurrentState) */
{
RetStatus = phHciNfc_System_Get_Info(
Hal4Ctxt->psHciHandle,
(void *)psHwReference,
IoctlCode ,
pOutParam->buffer
);
}
break;
/*Used to Read Memory/Registers .3 bytes of Array passed form the
address to read from in MSB first format.*/
case NFC_MEM_READ:
{
if((NULL != pInParam)
&& (pInParam->length == 3))
{
for( ind = 0; ind < 3; ind++ )
{
config_type = ((config_type << BYTE_SIZE )
| (pInParam->buffer[ind] ));
}
RetStatus = phHciNfc_System_Get_Info(
Hal4Ctxt->psHciHandle,
(void *)psHwReference,
config_type ,
pOutParam->buffer
);
}
else
{
RetStatus = PHNFCSTVAL(CID_NFC_HAL,
NFCSTATUS_INVALID_PARAMETER);
}
}
break;
/*Used to Write Memory/Registers .First 3 bytes of Array passed in MSB
first format form the address to write to.The 4th Byte is the 8 bit
value to be written to the address*/
case NFC_MEM_WRITE:
{
if((NULL != pInParam)
&& (pInParam->length == 4))
{
for( ind = 0; ind < 3; ind++ )
{
config_type = ((config_type << BYTE_SIZE )
| (pInParam->buffer[ind] ));
}
RetStatus = phHciNfc_System_Configure (
Hal4Ctxt->psHciHandle,
(void *)psHwReference,
config_type,
pInParam->buffer[3] /*config value*/
);
}
else
{
RetStatus = PHNFCSTVAL(CID_NFC_HAL ,
NFCSTATUS_INVALID_PARAMETER);
}
}
break;
default:
break;
}
if(NFCSTATUS_PENDING == RetStatus)/*Callback Pending*/
{
/*Register upper layer callback and context*/
Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb= pIoctlCallback;
/*Store the Ioctl code*/
Hal4Ctxt->Ioctl_Type = IoctlCode;
}
}
return RetStatus;
}
/**
* The close function called by the upper layer when HAL4 is to be closed
* (shutdown).
*/
NFCSTATUS phHal4Nfc_Close(
phHal_sHwReference_t *psHwReference,
pphHal4Nfc_GenCallback_t pCloseCallback,
void *pContext
)
{
NFCSTATUS closeRetVal = NFCSTATUS_SUCCESS;
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
/*NULL checks*/
if(NULL == psHwReference || NULL == pCloseCallback)
{
phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
closeRetVal = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
}
else if((NULL == psHwReference->hal_context)
|| (((phHal4Nfc_Hal4Ctxt_t *)
psHwReference->hal_context)->Hal4CurrentState
< eHal4StateSelfTestMode)
|| (((phHal4Nfc_Hal4Ctxt_t *)
psHwReference->hal_context)->Hal4NextState
== eHal4StateClosed))
{
/*return already closed*/
closeRetVal= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
}
else /*Close the HAL*/
{
/*Get Hal4 context from Hw reference*/
Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)((phHal_sHwReference_t *)
psHwReference)->hal_context;
/*Unregister Tag Listener*/
if(NULL != Hal4Ctxt->psADDCtxtInfo)
{
Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL;
}
/*store Callback and Context*/
Hal4Ctxt->sUpperLayerInfo.pUpperCloseCb = pCloseCallback;
Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
/*Call Hci Release*/
PHDBG_INFO("Hal4:Calling Hci Release");
closeRetVal =(NFCSTATUS)phHciNfc_Release(
(void *)Hal4Ctxt->psHciHandle,
psHwReference,
(pphNfcIF_Notification_CB_t)
phHal4Nfc_LowerNotificationHandler,
(void *)Hal4Ctxt
);
/*Update Next state and exit*/
if( PHNFCSTATUS (closeRetVal) == NFCSTATUS_PENDING )
{
Hal4Ctxt->Hal4NextState = eHal4StateClosed;
Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL;
}
else
{
}
}
return closeRetVal;
}
/*Forcibly shutdown the HAl4.Frees all Resources in use by Hal4 before shutting
down*/
void phHal4Nfc_Hal4Reset(
phHal_sHwReference_t *pHwRef,
void *pContext
)
{
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
NFCSTATUS closeRetVal = NFCSTATUS_SUCCESS;
uint8_t RemoteDevNumber = 0;
if(pHwRef ==NULL)
{
closeRetVal = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
}
else if(pHwRef->hal_context != NULL)
{
/*Get the Hal context*/
Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)pHwRef->hal_context;
/*store the upper layer context*/
Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
Hal4Ctxt->Hal4NextState = eHal4StateClosed;
Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL;
/*Call Hci Release*/
PHDBG_INFO("Hal4:Calling Hci Release");
closeRetVal =(NFCSTATUS)phHciNfc_Release(
(void *)Hal4Ctxt->psHciHandle,
pHwRef,
(pphNfcIF_Notification_CB_t)NULL,
(void *)Hal4Ctxt
);/*Clean up Hci*/
Hal4Ctxt->Hal4CurrentState = eHal4StateClosed;
phOsalNfc_FreeMemory((void *)Hal4Ctxt->pHal4Nfc_LayerCfg);
Hal4Ctxt->pHal4Nfc_LayerCfg = NULL;
/*Free ADD context*/
if(NULL != Hal4Ctxt->psADDCtxtInfo)
{
Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL;
while(RemoteDevNumber < MAX_REMOTE_DEVICES)
{
if(NULL != Hal4Ctxt->rem_dev_list[RemoteDevNumber])
{
phOsalNfc_FreeMemory((void *)
(Hal4Ctxt->rem_dev_list[RemoteDevNumber]));
Hal4Ctxt->rem_dev_list[RemoteDevNumber] = NULL;
}
RemoteDevNumber++;
}
Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
phOsalNfc_FreeMemory(Hal4Ctxt->psADDCtxtInfo);
}
/*Free Trcv context*/
if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
{
if(NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer)
{
phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo
->sLowerRecvData.buffer);
}
if((NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
&& (NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData))
{
phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData);
}
phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo);
}
phOsalNfc_FreeMemory(Hal4Ctxt);/*Free the context*/
pHwRef->hal_context = NULL;
gpphHal4Nfc_Hwref = NULL;
}
else
{
/*Hal4 Context is already closed.Return Success*/
}
/*Reset Should always return Success*/
if(closeRetVal != NFCSTATUS_SUCCESS)
{
phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
}
return;
}
/**
* \if hal
* \ingroup grp_hal_common
* \else
* \ingroup grp_mw_external_hal_funcs
* \endif
*
* Retrieves the capabilities of the device represented by the Hardware
* Reference parameter.
* The HW, SW versions, the MTU and other mandatory information are located
* inside the pDevCapabilities parameter.
*/
NFCSTATUS phHal4Nfc_GetDeviceCapabilities(
phHal_sHwReference_t *psHwReference,
phHal_sDeviceCapabilities_t *psDevCapabilities,
void *pContext
)
{
NFCSTATUS retstatus = NFCSTATUS_SUCCESS;
/*NULL checks*/
if(psDevCapabilities == NULL || psHwReference == NULL || pContext == NULL)
{
retstatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
}
/*Check for Initialized state*/
else if((NULL == psHwReference->hal_context)
|| (((phHal4Nfc_Hal4Ctxt_t *)
psHwReference->hal_context)->Hal4CurrentState
< eHal4StateOpenAndReady)
|| (((phHal4Nfc_Hal4Ctxt_t *)
psHwReference->hal_context)->Hal4NextState
== eHal4StateClosed))
{
retstatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED);
}
else/*Provide Device capabilities and Version Info to the caller*/
{
(void)memcpy((void *)psDevCapabilities,
(void *)&(psHwReference->device_info),
sizeof(phHal_sDeviceCapabilities_t));
psDevCapabilities->ReaderSupProtocol.Felica = TRUE;
psDevCapabilities->ReaderSupProtocol.ISO14443_4A = TRUE;
psDevCapabilities->ReaderSupProtocol.ISO14443_4B = TRUE;
psDevCapabilities->ReaderSupProtocol.ISO15693 = TRUE;
psDevCapabilities->ReaderSupProtocol.Jewel = TRUE;
psDevCapabilities->ReaderSupProtocol.MifareStd = TRUE;
psDevCapabilities->ReaderSupProtocol.MifareUL = TRUE;
psDevCapabilities->ReaderSupProtocol.NFC = TRUE;
psDevCapabilities->EmulationSupProtocol.Felica = FALSE;
psDevCapabilities->EmulationSupProtocol.ISO14443_4A = FALSE;
psDevCapabilities->EmulationSupProtocol.ISO14443_4B = FALSE;
psDevCapabilities->EmulationSupProtocol.ISO15693 = FALSE;
psDevCapabilities->EmulationSupProtocol.Jewel = FALSE;
psDevCapabilities->EmulationSupProtocol.MifareStd = FALSE;
psDevCapabilities->EmulationSupProtocol.MifareUL = FALSE;
psDevCapabilities->EmulationSupProtocol.NFC = TRUE;
psDevCapabilities->hal_version = (
(((PH_HAL4NFC_INTERFACE_VERSION << BYTE_SIZE)
|(PH_HAL4NFC_INTERFACE_REVISION)<<BYTE_SIZE)
|(PH_HAL4NFC_INTERFACE_PATCH)<<BYTE_SIZE)
|PH_HAL4NFC_INTERAFECE_BUILD
);
}
return retstatus;
}
/*
* Handles all notifications received from HCI layer.
*
*/
static void phHal4Nfc_LowerNotificationHandler(
void *pContext,
void *pHwRef,
uint8_t type,
void *pInfo
)
{
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
if((NULL == pInfo) || (NULL == pHwRef)
|| (NULL == pContext))
{
phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
}
else
{
/*A copy of hardware reference is maintained in HAL for comparing passed
and returned context.Set to NULL after a Shutdown*/
if(NULL != gpphHal4Nfc_Hwref)/*Get context from Hw ref*/
{
Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)gpphHal4Nfc_Hwref->hal_context;
if(NFC_INVALID_RELEASE_TYPE == Hal4Ctxt->sTgtConnectInfo.ReleaseType)
{
Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)pContext;
gpphHal4Nfc_Hwref = (phHal_sHwReference_t *)pHwRef;
}
}
else/*No Copy of Hw ref in HAL.Copy both Hwref and Hal context passed
by Hci*/
{
Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)pContext;
gpphHal4Nfc_Hwref = (phHal_sHwReference_t *)pHwRef;
}
/*Check the type of notification received from Hci and handle it
accordingly*/
switch(type)
{
case NFC_NOTIFY_INIT_COMPLETED:
case NFC_NOTIFY_INIT_FAILED:
phHal4Nfc_OpenComplete(Hal4Ctxt,pInfo);
break;
case NFC_IO_SUCCESS:
case NFC_IO_ERROR:
phHal4Nfc_IoctlComplete(Hal4Ctxt,pInfo);
break;
case NFC_NOTIFY_RESULT:
phHal4Nfc_SelfTestComplete(Hal4Ctxt,pInfo);
break;
case NFC_NOTIFY_DEINIT_COMPLETED:
case NFC_NOTIFY_DEINIT_FAILED:
phHal4Nfc_CloseComplete(Hal4Ctxt,pInfo);
break;
case NFC_NOTIFY_POLL_ENABLED:
case NFC_NOTIFY_POLL_DISABLED:
case NFC_NOTIFY_POLL_RESTARTED:
case NFC_NOTIFY_CONFIG_ERROR:
case NFC_NOTIFY_CONFIG_SUCCESS:
phHal4Nfc_ConfigureComplete(Hal4Ctxt,pInfo,type);
break;
case NFC_NOTIFY_TARGET_DISCOVERED:
case NFC_NOTIFY_DISCOVERY_ERROR:
phHal4Nfc_TargetDiscoveryComplete(Hal4Ctxt,pInfo);
break;
case NFC_NOTIFY_TARGET_REACTIVATED:
phHal4Nfc_ReactivationComplete(Hal4Ctxt,pInfo);
break;
case NFC_NOTIFY_EVENT:
PHDBG_INFO("Hal4:Calling Event callback");
phHal4Nfc_HandleEvent(Hal4Ctxt,pInfo);
break;
case NFC_NOTIFY_TARGET_CONNECTED:
PHDBG_INFO("Hal4:Calling Hal4 Connect complete");
phHal4Nfc_ConnectComplete(Hal4Ctxt,pInfo);
break;
case NFC_NOTIFY_TARGET_DISCONNECTED:
{
PHDBG_INFO("Hal4:Target Disconnected");
if(Hal4Ctxt->Hal4NextState == eHal4StatePresenceCheck)
{
phHal4Nfc_PresenceChkComplete(Hal4Ctxt,pInfo);
}
else
{
phHal4Nfc_DisconnectComplete(Hal4Ctxt,pInfo);
}
break;
}
case NFC_NOTIFY_TRANSCEIVE_COMPLETED:
case NFC_NOTIFY_TRANSCEIVE_ERROR :
PHDBG_INFO("Hal4:Transceive Callback");
if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
{
#ifdef TRANSACTION_TIMER
if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
!= PH_OSALNFC_INVALID_TIMER_ID)
{
phOsalNfc_Timer_Stop(
Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
);
phOsalNfc_Timer_Delete(
Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
);
Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
= PH_OSALNFC_INVALID_TIMER_ID;
}
#endif /*TRANSACTION_TIMER*/
phHal4Nfc_TransceiveComplete(Hal4Ctxt,pInfo);
}
break;
case NFC_NOTIFY_SEND_COMPLETED :
PHDBG_INFO("Hal4:NfcIp1 Send Callback");
if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
{
phHal4Nfc_SendCompleteHandler(Hal4Ctxt,pInfo);
}
break;
case NFC_NOTIFY_TRANSACTION :
phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
break;
case NFC_NOTIFY_RECV_ERROR :
case NFC_NOTIFY_RECV_EVENT :
PHDBG_INFO("Hal4:Receive Event");
if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
{
if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
!= PH_OSALNFC_INVALID_TIMER_ID)
{
phOsalNfc_Timer_Stop(
Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
);
phOsalNfc_Timer_Delete(
Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
);
Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
= PH_OSALNFC_INVALID_TIMER_ID;
}
}
phHal4Nfc_RecvCompleteHandler(Hal4Ctxt,pInfo);
break;
case NFC_NOTIFY_TARGET_PRESENT:
phHal4Nfc_PresenceChkComplete(Hal4Ctxt,pInfo);
break;
case NFC_NOTIFY_DEVICE_ERROR:
{
NFCSTATUS status = NFCSTATUS_BOARD_COMMUNICATION_ERROR;
pphHal4Nfc_GenCallback_t pUpper_OpenCb
= Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb;
void *pUpper_Context
= Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
static phHal4Nfc_NotificationInfo_t uNotificationInfo;
if(NULL != Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler)
{
Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler(
Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt,
NFC_EVENT_NOTIFICATION,
uNotificationInfo,
NFCSTATUS_BOARD_COMMUNICATION_ERROR
);
}
else if (( eHal4StateSelfTestMode == Hal4Ctxt->Hal4NextState )
|| ( eHal4StateOpenAndReady == Hal4Ctxt->Hal4NextState ) )
{
Hal4Ctxt->Hal4CurrentState = eHal4StateClosed;
Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
(void)phHciNfc_Release((void *)Hal4Ctxt->psHciHandle,
pHwRef, (pphNfcIF_Notification_CB_t)NULL,
(void *)Hal4Ctxt);/*Clean up Hci*/
Hal4Ctxt->psHciHandle = NULL;
phOsalNfc_FreeMemory((void *)Hal4Ctxt->pHal4Nfc_LayerCfg);
Hal4Ctxt->pHal4Nfc_LayerCfg = NULL;
phOsalNfc_FreeMemory((void *)Hal4Ctxt);
gpphHal4Nfc_Hwref->hal_context = NULL;
gpphHal4Nfc_Hwref = NULL;
PHDBG_INFO("Hal4:Open Failed");
/*Call upper layer's Open Cb with error status*/
if(NULL != pUpper_OpenCb)
{
/*Upper layer's Open Cb*/
(*pUpper_OpenCb)(pUpper_Context,status);
}
}
else
{
Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1);
}
break;
}
case NFC_NOTIFY_CONNECT_FAILED:
case NFC_NOTIFY_DISCONNECT_FAILED:
/*Generic Error type received from Hci.Handle the error based on
Hal4 next state and which past callback was Pending*/
case NFC_NOTIFY_ERROR:
{
PHDBG_WARNING("Hal4:Error Notification from HCI");
switch(Hal4Ctxt->Hal4NextState)
{
case eHal4StateClosed:
phHal4Nfc_CloseComplete(Hal4Ctxt,pInfo);
break;
case eHal4StateSelfTestMode:
phHal4Nfc_SelfTestComplete(Hal4Ctxt,pInfo);
break;
case eHal4StateConfiguring:
phHal4Nfc_ConfigureComplete(Hal4Ctxt,pInfo,type);
break;
case eHal4StateTargetDiscovered:
case eHal4StateTargetActivate:
{
if(NULL != Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb)
{
if(NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
{
phHal4Nfc_ConfigureComplete(Hal4Ctxt,pInfo,type);
}
else
{
phHal4Nfc_ConnectComplete(Hal4Ctxt,pInfo);
}
}
else
{
phHal4Nfc_TargetDiscoveryComplete(Hal4Ctxt,pInfo);
}
break;
}
case eHal4StateTargetConnected:
phHal4Nfc_ConnectComplete(Hal4Ctxt,pInfo);
break;
case eHal4StateOpenAndReady:
phHal4Nfc_DisconnectComplete(Hal4Ctxt,pInfo);
break;
case eHal4StatePresenceCheck:
phHal4Nfc_PresenceChkComplete(Hal4Ctxt,pInfo);
break;
default:
PHDBG_WARNING("Unknown Error notification");
break;
}
break;
}/*End of switch(Hal4Ctxt->Hal4State)*/
default:
phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
break;
}/*End of switch(type)*/
}
return;
}
/*Event handler for HAL-HCI interface*/
static void phHal4Nfc_HandleEvent(
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,
void *pInfo
)
{
phHal_sEventInfo_t *psEventInfo = (phHal_sEventInfo_t *)pInfo;
static phNfc_sNotificationInfo_t sNotificationInfo;
phHal4Nfc_NotificationInfo_t uNotificationInfo = {NULL};
NFCSTATUS RetStatus = NFCSTATUS_FAILED;
/*Check if Hal4 Close has already been called*/
if(eHal4StateClosed != Hal4Ctxt->Hal4NextState)
{
switch(psEventInfo->eventType)
{
case NFC_EVT_ACTIVATED:/*Target Activated*/
{
if(psEventInfo->eventHost == phHal_eHostController)
{
switch(psEventInfo->eventSource)
{
case phHal_eNfcIP1_Target:
phHal4Nfc_P2PActivateComplete(Hal4Ctxt,pInfo);
break;
case phHal_eISO14443_A_PICC:
case phHal_eISO14443_B_PICC:
sNotificationInfo.info = psEventInfo;
sNotificationInfo.status = NFCSTATUS_SUCCESS;
sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
pInfo = &sNotificationInfo;
phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
break;
default:
break;
}
}
}
break;
case NFC_EVT_DEACTIVATED:/*Target Deactivated*/
{
if(psEventInfo->eventHost == phHal_eHostController)
{
switch(psEventInfo->eventSource)
{
case phHal_eNfcIP1_Target:
phHal4Nfc_HandleP2PDeActivate(Hal4Ctxt,pInfo);
break;
case phHal_eISO14443_A_PICC:
case phHal_eISO14443_B_PICC:
sNotificationInfo.info = psEventInfo;
sNotificationInfo.status = NFCSTATUS_SUCCESS;
sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
pInfo = &sNotificationInfo;
phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
break;
default:
break;
}
}
}
break;
/*Set Protection Event*/
case NFC_EVT_PROTECTED:
{
#ifdef IGNORE_EVT_PROTECTED
/*Ignore_Event_Protected is set to false during Field Off event and
Set protection Configuration.After a NFC_EVT_PROTECTED is received
once all subsequent NFC_EVT_PROTECTED events are ignored*/
if(FALSE == Hal4Ctxt->Ignore_Event_Protected)
{
Hal4Ctxt->Ignore_Event_Protected = TRUE;
#endif/*#ifdef IGNORE_EVT_PROTECTED*/
sNotificationInfo.info = psEventInfo;
sNotificationInfo.status = NFCSTATUS_SUCCESS;
sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
pInfo = &sNotificationInfo;
phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
#ifdef IGNORE_EVT_PROTECTED
}
#endif/*#ifdef IGNORE_EVT_PROTECTED*/
break;
}
/*NFC_UICC_RDPHASES_DEACTIVATE_REQ*/
case NFC_UICC_RDPHASES_DEACTIVATE_REQ:
{
if(NULL != gpphHal4Nfc_Hwref)
{
gpphHal4Nfc_Hwref->uicc_rdr_active = FALSE;
}
break;
}
case NFC_UICC_RDPHASES_ACTIVATE_REQ:
{
if(NULL != gpphHal4Nfc_Hwref)
{
gpphHal4Nfc_Hwref->uicc_rdr_active = TRUE;
}
/*If a NFC_UICC_RDPHASES_ACTIVATE_REQ is received before a configure
discovery,then create a ADD context info*/
if (NULL == Hal4Ctxt->psADDCtxtInfo)
{
Hal4Ctxt->psADDCtxtInfo= (pphHal4Nfc_ADDCtxtInfo_t)
phOsalNfc_GetMemory((uint32_t)
(sizeof(phHal4Nfc_ADDCtxtInfo_t)));
if(NULL != Hal4Ctxt->psADDCtxtInfo)
{
(void)memset(Hal4Ctxt->psADDCtxtInfo,0,
sizeof(phHal4Nfc_ADDCtxtInfo_t)
);
}
}
if(NULL != Hal4Ctxt->psADDCtxtInfo)
{
Hal4Ctxt->psADDCtxtInfo->sADDCfg.PollDevInfo.PollEnabled
|= psEventInfo->eventInfo.rd_phases;
/*Configure HCI Discovery*/
RetStatus = phHciNfc_Config_Discovery(
(void *)Hal4Ctxt->psHciHandle,
gpphHal4Nfc_Hwref,
&(Hal4Ctxt->psADDCtxtInfo->sADDCfg)
);
Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == RetStatus?
eHal4StateConfiguring:
Hal4Ctxt->Hal4NextState);
}
break;
}
/*Call Default Event handler for these Events*/
case NFC_INFO_TXLDO_OVERCUR:
case NFC_INFO_MEM_VIOLATION:
case NFC_INFO_TEMP_OVERHEAT:
case NFC_INFO_LLC_ERROR:
{
sNotificationInfo.info = psEventInfo;
sNotificationInfo.status = NFCSTATUS_SUCCESS;
sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
pInfo = &sNotificationInfo;
PHDBG_INFO("Hal4:Exception events");
if(NULL != Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler)
{
/*Pass on Event notification info from Hci to Upper layer*/
uNotificationInfo.psEventInfo = psEventInfo;
Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler(
Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt,
sNotificationInfo.type,
uNotificationInfo,
NFCSTATUS_SUCCESS
);
}
break;
}
/*Call emulation Event handler fto handle these Events*/
case NFC_EVT_TRANSACTION:
case NFC_EVT_START_OF_TRANSACTION:
case NFC_EVT_END_OF_TRANSACTION:
case NFC_EVT_CONNECTIVITY:
case NFC_EVT_OPERATION_ENDED:
case NFC_EVT_MIFARE_ACCESS:
case NFC_EVT_APDU_RECEIVED:
case NFC_EVT_EMV_CARD_REMOVAL:
sNotificationInfo.info = psEventInfo;
sNotificationInfo.status = NFCSTATUS_SUCCESS;
sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
pInfo = &sNotificationInfo;
PHDBG_INFO("Hal4:Event transaction\n");
phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
break;
case NFC_EVT_FIELD_ON:
Hal4Ctxt->psEventInfo = sNotificationInfo.info = psEventInfo;
sNotificationInfo.status = NFCSTATUS_SUCCESS;
sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
pInfo = &sNotificationInfo;
PHDBG_INFO("Hal4:Event Field ON\n");
phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
break;
case NFC_EVT_FIELD_OFF:
#ifdef IGNORE_EVT_PROTECTED
Hal4Ctxt->Ignore_Event_Protected = FALSE;
#endif/*#ifdef IGNORE_EVT_PROTECTED*/
Hal4Ctxt->psEventInfo = sNotificationInfo.info = psEventInfo;
sNotificationInfo.status = NFCSTATUS_SUCCESS;
sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
pInfo = &sNotificationInfo;
PHDBG_INFO("Hal4:Event Field OFF\n");
phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
break;
default:
PHDBG_WARNING("Hal4:Unhandled Event type received");
break;
}/*End of switch*/
}/*if(eHal4StateClosed != Hal4Ctxt->Hal4NextState)*/
return;
}
/*Callback handler for Self Test Ioctl completion*/
static void phHal4Nfc_SelfTestComplete(
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,
void *pInfo
)
{
NFCSTATUS status = NFCSTATUS_FAILED;
phNfc_sData_t *SelfTestResults
= (phNfc_sData_t *)(((phNfc_sCompletionInfo_t *)pInfo)->info);
pphHal4Nfc_IoctlCallback_t pUpper_IoctlCb
= Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb;
void *pUpper_Context = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
/*check for Success*/
if(( DEVMGMT_SWP_TEST == Hal4Ctxt->Ioctl_Type )
|| ( DEVMGMT_ANTENNA_TEST == Hal4Ctxt->Ioctl_Type ))
{
status = NFCSTATUS_SUCCESS;
}
else if((SelfTestResults->length > 0) && (0 == SelfTestResults->buffer[0]))
{
status = NFCSTATUS_SUCCESS;
}
else
{
if (NULL != pInfo)
{
status = ((phNfc_sCompletionInfo_t *)pInfo)->status;
}
}
/*Copy response buffer and length*/
(void)memcpy(Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam->buffer,
SelfTestResults->buffer,
SelfTestResults->length);
Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam->length
= SelfTestResults->length;
/*Call registered Ioctl callback*/
(*pUpper_IoctlCb)(
pUpper_Context,
Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam,
status
);
return;
}
static void phHal4Nfc_IoctlComplete(
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,
void *pInfo
)
{
/*Copy status*/
NFCSTATUS status = (((phNfc_sCompletionInfo_t *)pInfo)->status);
pphHal4Nfc_IoctlCallback_t pUpper_IoctlCb
= Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb;
#ifdef MERGE_SAK_SW2
pphHal4Nfc_GenCallback_t pConfigCallback =
Hal4Ctxt->sUpperLayerInfo.pConfigCallback;
#endif/*#ifdef MERGE_SAK_SW2*/
void *pUpper_Context = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb = NULL;
#ifdef MERGE_SAK_SW1 /*Software workaround 1*/
if(eHal4StateOpenAndReady == Hal4Ctxt->Hal4NextState)
{
Hal4Ctxt->Hal4CurrentState = Hal4Ctxt->Hal4NextState;
Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
/*Upper layer's Open Cb*/
(*Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb)(
Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
NFCSTATUS_SUCCESS
);
}
#endif/*#ifdef MERGE_SAK_SW1*/
#ifdef MERGE_SAK_SW2 /*Software workaround 2*/
else if((eHal4StateConfiguring == Hal4Ctxt->Hal4NextState)
&&(NULL != pConfigCallback))
{
Hal4Ctxt->sUpperLayerInfo.pConfigCallback = NULL;
Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
(*pConfigCallback)(
Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,status
);
}
else
#endif/*#ifdef MERGE_SAK_SW2*/
{
/*for NFC_MEM_READ and NFC_GPIO_READ ,provide one Byte Response*/
if ((NFC_MEM_READ == Hal4Ctxt->Ioctl_Type)
|| (NFC_GPIO_READ == Hal4Ctxt->Ioctl_Type)
)
{
Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam->length
= sizeof (uint8_t);
}
/*Call registered Ioctl callback*/
if(NULL != pUpper_IoctlCb)
{
(*pUpper_IoctlCb)(
pUpper_Context,
Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam,
status
);
}
}
return;
}
#ifdef FW_DOWNLOAD
/**Callback handler for Download completion*/
STATIC void phHal4Nfc_DownloadComplete(
void *pContext,
void *pHwRef,
uint8_t type,
void *pInfo
)
{
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
NFCSTATUS status = NFCSTATUS_FAILED;
pphHal4Nfc_IoctlCallback_t pUpper_DnldCb = NULL;
phNfc_sData_t *pIoctlOutParam = NULL;
phHal_sHwReference_t *psHwRef = NULL;
void *pUpper_Context = NULL;
/*NULL checks*/
if((NULL == pInfo) || (NULL == pHwRef) || (NULL == pContext))
{
phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
}
else
{
type = type;
Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)pContext;
/*Copy back stored context/callback for the upper layer*/
pUpper_Context = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
pIoctlOutParam = Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam;
pUpper_DnldCb = Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb;
Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb = NULL;
/*Copy download status*/
status = (((phNfc_sCompletionInfo_t *)pInfo)->status);
/*copy hw reference*/
psHwRef = (phHal_sHwReference_t *)pHwRef;
/*Free the temporary hal context used only for the sake of download*/
phOsalNfc_FreeMemory(psHwRef->hal_context);
psHwRef->hal_context = NULL;
/*Call upper layer callback*/
if(NULL != pUpper_DnldCb)
{
(*pUpper_DnldCb)(
pUpper_Context,
pIoctlOutParam,
status
);
}
}
return;
}
#endif /*FW_DOWNLOAD*/