blob: 2a03c059d674430e90aac5622e6355c44e1a9dfd [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_initiator.c
* Project: NFC FRI 1.1
*
* $Date: Fri Apr 23 14:34:08 2010 $
* $Author: ing07385 $
* $Revision: 1.53 $
* $Aliases: NFC_FRI1.1_WK1014_SDK,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1019_SDK,NFC_FRI1.1_WK1024_SDK $
*
*/
/*
************************* Header Files ****************************************
*/
#include <phLibNfcStatus.h>
#include <phLibNfc.h>
#include <phHal4Nfc.h>
#include <phOsalNfc.h>
#include <phLibNfc_Internal.h>
#include <phLibNfc_SE.h>
#include <phLibNfc_ndef_raw.h>
#include <phLibNfc_initiator.h>
#include <phLibNfc_discovery.h>
/*
*************************** Macro's ****************************************
*/
#ifndef STATIC_DISABLE
#define STATIC static
#else
#define STATIC
#endif
/*
*************************** Global Variables **********************************
*/
#define PN544_IO_TIMEOUT_RESPONSE 0x89
/*
*************************** Static Function Declaration ***********************
*/
/* Target discvovery notification callback */
STATIC void phLibNfc_NotificationRegister_Resp_Cb (
void *context,
phHal_eNotificationType_t type,
phHal4Nfc_NotificationInfo_t info,
NFCSTATUS status
);
/*Remote device connect response callback*/
STATIC void phLibNfc_RemoteDev_Connect_Cb(
void *pContext,
phHal_sRemoteDevInformation_t *pRmtdev_info,
NFCSTATUS status
);
#ifdef RECONNECT_SUPPORT
STATIC
void
phLibNfc_config_discovery_con_failure_cb (
void *context,
NFCSTATUS status);
#endif /* #ifdef RECONNECT_SUPPORT */
/*Remote device disconnect response callback*/
STATIC void phLibNfc_RemoteDev_Disconnect_cb(
void *context,
phHal_sRemoteDevInformation_t *reg_handle,
NFCSTATUS status
);
/*Remote device Transceive response callback*/
STATIC void phLibNfc_RemoteDev_Transceive_Cb(void *context,
phHal_sRemoteDevInformation_t *pRmtdev_info,
phNfc_sData_t *response,
NFCSTATUS status
);
/*Set P2P config paramater response callback*/
STATIC void phLibNfc_Mgt_SetP2P_ConfigParams_Cb(
void *context,
NFCSTATUS status
);
/*
*************************** Function Definitions ******************************
*/
/**
* Response to target discovery.
*/
STATIC
void phLibNfc_NotificationRegister_Resp_Cb (
void *context,
phHal_eNotificationType_t type,
phHal4Nfc_NotificationInfo_t info,
NFCSTATUS status
)
{
NFCSTATUS RetVal = NFCSTATUS_SUCCESS,
Status = NFCSTATUS_SUCCESS;
uint16_t DeviceIndx, DeviceIndx1;
uint8_t sak_byte=0;
uint8_t tag_disc_flg = 0;
phLibNfc_NtfRegister_RspCb_t pClientCb=NULL;
pClientCb =gpphLibContext->CBInfo.pClientNtfRegRespCB;
PHNFC_UNUSED_VARIABLE(context);
if(( type != NFC_DISCOVERY_NOTIFICATION )
&&(PHNFCSTATUS(status)!=NFCSTATUS_DESELECTED))
{
Status = NFCSTATUS_FAILED;
}
else
{
DeviceIndx=0;DeviceIndx1=0;
while(DeviceIndx < info.psDiscoveryInfo->NumberOfDevices)
{
switch(info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx]->RemDevType)
{
case phHal_eMifare_PICC:
{
/*Mifare Tag discovered*/
sak_byte = info.psDiscoveryInfo->
ppRemoteDevInfo[DeviceIndx]->RemoteDevInfo.Iso14443A_Info.Sak;
if((TRUE == gpphLibContext->RegNtfType.MifareUL)&& (sak_byte==0x00))
{
/*Copy the tag related info*/
gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
gpphLibContext->Discov_handle[DeviceIndx1] =
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
DeviceIndx1++;
tag_disc_flg++;
}
if((TRUE == gpphLibContext->RegNtfType.MifareStd)&&
(((sak_byte & 0x18)==0x08)||((sak_byte & 0x18)==0x18)))
{
/*Copy the tag related info*/
gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
gpphLibContext->Discov_handle[DeviceIndx1]=
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
DeviceIndx1++;
tag_disc_flg++;
}
}break;
case phHal_eISO14443_A_PICC:
{
/*ISO 14443-A type tag discovered*/
if(TRUE == gpphLibContext->RegNtfType.ISO14443_4A)
{
/*Copy the ISO type A tag info*/
gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
gpphLibContext->Discov_handle[DeviceIndx1] =
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
DeviceIndx1++;
tag_disc_flg++;
}
}break;
case phHal_eISO14443_3A_PICC:
{
/*ISO 14443-A type tag discovered*/
if(TRUE == gpphLibContext->RegNtfType.MifareUL)
{
/*Copy the ISO type A tag info*/
gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
gpphLibContext->Discov_handle[DeviceIndx1] =
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
DeviceIndx1++;
tag_disc_flg++;
}
}break;
case phHal_eISO14443_B_PICC:
{
/*ISO 14443-B type tag Discovered */
if(TRUE == gpphLibContext->RegNtfType.ISO14443_4B)
{
/*Copy the Type B tag info */
gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
gpphLibContext->Discov_handle[DeviceIndx1] =
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
DeviceIndx1++;
tag_disc_flg++;
}
}break;
case phHal_eFelica_PICC:
{
/*Felica Type Tag Discovered */
if(TRUE == gpphLibContext->RegNtfType.Felica)
{
/*Copy the Felica tag info */
gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
gpphLibContext->Discov_handle[DeviceIndx1] =
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
DeviceIndx1++;
tag_disc_flg++;
}
}break;
case phHal_eJewel_PICC:
{
/*Jewel Type Tag Discovered */
if(TRUE == gpphLibContext->RegNtfType.Jewel)
{
/*Copy the Felica tag info */
gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
gpphLibContext->Discov_handle[DeviceIndx1] =
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
DeviceIndx1++;
tag_disc_flg++;
}
}
break;
case phHal_eISO15693_PICC:
{
/*Jewel Type Tag Discovered */
if(TRUE == gpphLibContext->RegNtfType.ISO15693)
{
/*Copy the Felica tag info */
gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
gpphLibContext->Discov_handle[DeviceIndx1] =
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
DeviceIndx1++;
tag_disc_flg++;
}
}
break;
case phHal_eNfcIP1_Target:
{
if(TRUE == gpphLibContext->RegNtfType.NFC)
{
gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
gpphLibContext->Discov_handle[DeviceIndx1] =
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
DeviceIndx1++;
tag_disc_flg++;
}
}
break;
case phHal_eNfcIP1_Initiator:
{
if(TRUE == gpphLibContext->RegNtfType.NFC)
{
gpphLibContext->LibNfcState.cur_state=eLibNfcHalStateConnect;
gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
(uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo;
gpphLibContext->sNfcIp_Context.Rem_Initiator_Handle=
gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
DeviceIndx1++;
tag_disc_flg++;
}
}
break;
default :
{
break;
}
}
DeviceIndx++;
}
}
if((tag_disc_flg >0 )&&(status != NFCSTATUS_FAILED))
{
gpphLibContext->dev_cnt = tag_disc_flg;
/* Check for if the discovered tags are multiple or
Multiple protocol tag */
if((gpphLibContext->dev_cnt > 1)&&(
(status ==NFCSTATUS_MULTIPLE_PROTOCOLS) ||
(status ==NFCSTATUS_MULTIPLE_TAGS)) )
{
status = status;
}
else
{
status =NFCSTATUS_SUCCESS;
}
/*Notify to upper layer the no of tag discovered and
the protocol */
if (NULL != pClientCb)
{
pClientCb(
(void*)gpphLibContext->CBInfo.pClientNtfRegRespCntx,
gpphLibContext->psRemoteDevList,
gpphLibContext->dev_cnt,
status
);
}
}
else if(PHNFCSTATUS(status)==NFCSTATUS_DESELECTED)
{
info.psDiscoveryInfo->NumberOfDevices = 0;
if (NULL != pClientCb)
{
gpphLibContext->LibNfcState.cur_state=eLibNfcHalStateRelease;
pClientCb((void*)gpphLibContext->CBInfo.pClientNtfRegRespCntx,
NULL,
0,
status);
}
}
else /*Reconfigure the discovery wheel*/
{
RetVal = phHal4Nfc_ConfigureDiscovery ( gpphLibContext->psHwReference,
NFC_DISCOVERY_RESUME,
&(gpphLibContext->sADDconfig),
phLibNfc_config_discovery_cb,
gpphLibContext);
if((RetVal!=NFCSTATUS_SUCCESS) &&(RetVal!=NFCSTATUS_PENDING))
{
Status = NFCSTATUS_FAILED;
}
}
if(Status == NFCSTATUS_FAILED)
{
if (NULL != pClientCb)
{
pClientCb(gpphLibContext->CBInfo.pClientNtfRegRespCntx,
NULL,
0,
Status);
}
}
return;
}
/**
* This interface registers notification handler for target discovery.
*/
NFCSTATUS
phLibNfc_RemoteDev_NtfRegister(
phLibNfc_Registry_Info_t* pRegistryInfo,
phLibNfc_NtfRegister_RspCb_t pNotificationHandler,
void *pContext
)
{
NFCSTATUS RetVal = NFCSTATUS_SUCCESS;
/*Check for valid parameters*/
if((NULL == pNotificationHandler)
|| (NULL == pContext)
||(NULL== pRegistryInfo))
{
RetVal= NFCSTATUS_INVALID_PARAMETER;
}
else if((NULL == gpphLibContext) ||
(gpphLibContext->LibNfcState.cur_state
== eLibNfcHalStateShutdown))
{
RetVal = NFCSTATUS_NOT_INITIALISED;
}
else if(gpphLibContext->LibNfcState.next_state
== eLibNfcHalStateShutdown)
{
/*Next state is shutdown*/
RetVal= NFCSTATUS_SHUTDOWN;
}
else
{
PHDBG_INFO("LibNfc:Registering Notification Handler");
(void) memcpy(&(gpphLibContext->RegNtfType),pRegistryInfo,
sizeof(phLibNfc_Registry_Info_t));
/* Register Discovery Notification Handler*/
/*Register for NFCIP1 target type*/
RetVal = phHal4Nfc_RegisterNotification(
gpphLibContext->psHwReference,
eRegisterP2PDiscovery,
phLibNfc_NotificationRegister_Resp_Cb,
(void*)gpphLibContext
);
/*Register for Tag discovery*/
RetVal = phHal4Nfc_RegisterNotification(
gpphLibContext->psHwReference,
eRegisterTagDiscovery,
phLibNfc_NotificationRegister_Resp_Cb,
(void*)gpphLibContext
);
gpphLibContext->CBInfo.pClientNtfRegRespCB = pNotificationHandler;
gpphLibContext->CBInfo.pClientNtfRegRespCntx = pContext;
/*Register notification handler with below layer*/
}
return RetVal;
}
/**
* This interface unregisters notification handler for target discovery.
*/
NFCSTATUS phLibNfc_RemoteDev_NtfUnregister(void)
{
NFCSTATUS RetVal = NFCSTATUS_SUCCESS;
if((NULL == gpphLibContext) ||
(gpphLibContext->LibNfcState.cur_state
== eLibNfcHalStateShutdown))
{
/*Lib Nfc not Initialized*/
RetVal = NFCSTATUS_NOT_INITIALISED;
}
else if(gpphLibContext->LibNfcState.next_state
== eLibNfcHalStateShutdown)
{
/*Lib Nfc Shutdown*/
RetVal= NFCSTATUS_SHUTDOWN;
}
else
{
/*Unregister notification handler with lower layer */
RetVal = phHal4Nfc_UnregisterNotification(
gpphLibContext->psHwReference,
eRegisterP2PDiscovery,
gpphLibContext);
RetVal = phHal4Nfc_UnregisterNotification(
gpphLibContext->psHwReference,
eRegisterTagDiscovery,
gpphLibContext);
gpphLibContext->CBInfo.pClientNtfRegRespCB = NULL;
gpphLibContext->CBInfo.pClientNtfRegRespCntx =NULL;
PHDBG_INFO("LibNfc:Unregister Notification Handler");
}
return RetVal;
}
#ifdef RECONNECT_SUPPORT
NFCSTATUS
phLibNfc_RemoteDev_ReConnect (
phLibNfc_Handle hRemoteDevice,
pphLibNfc_ConnectCallback_t pNotifyReConnect_RspCb,
void *pContext)
{
NFCSTATUS ret_val = NFCSTATUS_FAILED;
phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo = NULL;
if ((NULL == gpphLibContext)
|| (eLibNfcHalStateShutdown ==
gpphLibContext->LibNfcState.cur_state))
{
ret_val = NFCSTATUS_NOT_INITIALISED;
}
else if ((NULL == pContext)
|| (NULL == pNotifyReConnect_RspCb)
|| (NULL == (void *)hRemoteDevice))
{
/* Check valid parameters */
ret_val = NFCSTATUS_INVALID_PARAMETER;
}
/* Check valid lib nfc State */
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 ((gpphLibContext->Discov_handle[0] != hRemoteDevice)
&& (gpphLibContext->Discov_handle[1] != hRemoteDevice)
&& (gpphLibContext->Discov_handle[2] != hRemoteDevice)
&& (gpphLibContext->Discov_handle[3] != hRemoteDevice)
&& (gpphLibContext->Discov_handle[4] != hRemoteDevice)
&& (gpphLibContext->Discov_handle[5] != hRemoteDevice)
&& (gpphLibContext->Discov_handle[6] != hRemoteDevice)
&& (gpphLibContext->Discov_handle[7] != hRemoteDevice)
&& (gpphLibContext->Discov_handle[8] != hRemoteDevice)
&& (gpphLibContext->Discov_handle[9] != hRemoteDevice))
{
ret_val = NFCSTATUS_INVALID_HANDLE;
}
else
{
psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t *)hRemoteDevice;
/* Call the HAL connect*/
ret_val = phHal4Nfc_Connect (gpphLibContext->psHwReference,
psRemoteDevInfo,
phLibNfc_RemoteDev_Connect_Cb,
(void *)gpphLibContext);
if (NFCSTATUS_PENDING == ret_val)
{
/* If HAL Connect is pending update the LibNFC state machine
and store the CB pointer and Context,
mark the General CB pending status is TRUE */
gpphLibContext->CBInfo.pClientConnectCb = pNotifyReConnect_RspCb;
gpphLibContext->CBInfo.pClientConCntx = pContext;
gpphLibContext->status.GenCb_pending_status = TRUE;
gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect;
gpphLibContext->Prev_Connected_handle = gpphLibContext->Connected_handle;
gpphLibContext->Connected_handle = hRemoteDevice;
}
else if (NFCSTATUS_INVALID_REMOTE_DEVICE == PHNFCSTATUS(ret_val))
{
/* The Handle given for connect is invalid*/
ret_val = NFCSTATUS_TARGET_NOT_CONNECTED;
}
else
{
/* Lower layer returns internal error code return NFCSTATUS_FAILED*/
ret_val = NFCSTATUS_FAILED;
}
}
return ret_val;
}
#endif /* #ifdef RECONNECT_SUPPORT */
/**
* Connect to a single Remote Device
*/
NFCSTATUS phLibNfc_RemoteDev_Connect(
phLibNfc_Handle hRemoteDevice,
pphLibNfc_ConnectCallback_t pNotifyConnect_RspCb,
void *pContext
)
{
NFCSTATUS RetVal = NFCSTATUS_FAILED;
phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo;
if((NULL == gpphLibContext) ||
(gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
{
RetVal = NFCSTATUS_NOT_INITIALISED;
}/* Check valid parameters*/
else if((NULL == pContext)
|| (NULL == pNotifyConnect_RspCb)
|| (NULL == (void*)hRemoteDevice))
{
RetVal= NFCSTATUS_INVALID_PARAMETER;
}
/* Check valid lib nfc State*/
else if(gpphLibContext->LibNfcState.next_state
== eLibNfcHalStateShutdown)
{
RetVal= NFCSTATUS_SHUTDOWN;
}
else if((gpphLibContext->Discov_handle[0] != hRemoteDevice)&&
(gpphLibContext->Discov_handle[1] != hRemoteDevice)&&
(gpphLibContext->Discov_handle[2] != hRemoteDevice)&&
(gpphLibContext->Discov_handle[3] != hRemoteDevice)&&
(gpphLibContext->Discov_handle[4] != hRemoteDevice)&&
(gpphLibContext->Discov_handle[5] != hRemoteDevice)&&
(gpphLibContext->Discov_handle[6] != hRemoteDevice)&&
(gpphLibContext->Discov_handle[7] != hRemoteDevice)&&
(gpphLibContext->Discov_handle[8] != hRemoteDevice)&&
(gpphLibContext->Discov_handle[9] != hRemoteDevice))
{
RetVal= NFCSTATUS_INVALID_HANDLE;
}
else if ((hRemoteDevice != gpphLibContext->Connected_handle)
&& (0 != gpphLibContext->Connected_handle))
{
RetVal = NFCSTATUS_FAILED;
}
else
{
psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice;
/* Call the HAL connect*/
RetVal = phHal4Nfc_Connect(gpphLibContext->psHwReference,
psRemoteDevInfo,
phLibNfc_RemoteDev_Connect_Cb,
(void* )gpphLibContext);
if(RetVal== NFCSTATUS_PENDING)
{
/* If HAL Connect is pending update the LibNFC state machine
and store the CB pointer and Context,
mark the General CB pending status is TRUE*/
gpphLibContext->CBInfo.pClientConnectCb = pNotifyConnect_RspCb;
gpphLibContext->CBInfo.pClientConCntx = pContext;
gpphLibContext->status.GenCb_pending_status=TRUE;
gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect;
gpphLibContext->Prev_Connected_handle = gpphLibContext->Connected_handle;
gpphLibContext->Connected_handle = hRemoteDevice;
}
else if(PHNFCSTATUS(RetVal) == NFCSTATUS_INVALID_REMOTE_DEVICE)
{
/* The Handle given for connect is invalid*/
RetVal= NFCSTATUS_TARGET_NOT_CONNECTED;
}
else
{
/* Lower layer returns internal error code return NFCSTATUS_FAILED*/
RetVal = NFCSTATUS_FAILED;
}
}
return RetVal;
}
#ifdef RECONNECT_SUPPORT
STATIC
void
phLibNfc_config_discovery_con_failure_cb (
void *context,
NFCSTATUS status)
{
if((phLibNfc_LibContext_t *)context == gpphLibContext)
{ /*check for same context*/
pphLibNfc_ConnectCallback_t ps_client_con_cb =
gpphLibContext->CBInfo.pClientConnectCb;
if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
{
/*If shutdown called in between allow shutdown to happen*/
phLibNfc_Pending_Shutdown();
status = NFCSTATUS_SHUTDOWN;
}
else
{
gpphLibContext->status.GenCb_pending_status = FALSE;
gpphLibContext->status.DiscEnbl_status = FALSE;
status = NFCSTATUS_TARGET_LOST;
phLibNfc_UpdateCurState (status,gpphLibContext);
#ifdef RESTART_CFG
if(gpphLibContext->status.Discovery_pending_status == TRUE)
{
NFCSTATUS RetStatus = NFCSTATUS_FAILED;
/* Application has called discovery before receiving this callback,
so NO notification to the upper layer, instead lower layer
discovery is called */
gpphLibContext->status.Discovery_pending_status = FALSE;
RetStatus = phHal4Nfc_ConfigureDiscovery(
gpphLibContext->psHwReference,
gpphLibContext->eLibNfcCfgMode,
&gpphLibContext->sADDconfig,
(pphLibNfc_RspCb_t)
phLibNfc_config_discovery_cb,
(void *)gpphLibContext);
if (NFCSTATUS_PENDING == RetStatus)
{
(void)phLibNfc_UpdateNextState(gpphLibContext,
eLibNfcHalStateConfigReady);
gpphLibContext->status.GenCb_pending_status = TRUE;
gpphLibContext->status.DiscEnbl_status = TRUE;
}
}
#endif /* #ifdef RESTART_CFG */
}
if (NULL != ps_client_con_cb)
{
gpphLibContext->CBInfo.pClientConnectCb = NULL;
/* Call the upper layer callback*/
ps_client_con_cb (gpphLibContext->CBInfo.pClientConCntx,
0, NULL, status);
}
} /*End of if-context check*/
else
{ /*exception: wrong context pointer returned*/
phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
status = NFCSTATUS_FAILED;
}
}
#endif /* #ifdef RECONNECT_SUPPORT */
/**
* Response callback for remote device connect
*/
STATIC void phLibNfc_RemoteDev_Connect_Cb(
void *pContext,
phHal_sRemoteDevInformation_t *pRmtdev_info,
NFCSTATUS status
)
{
NFCSTATUS Connect_status = NFCSTATUS_SUCCESS;
/*Check valid lib nfc context is returned from lower layer*/
if((phLibNfc_LibContext_t *)pContext == gpphLibContext)
{
gpphLibContext->LastTrancvSuccess = FALSE;
/* Mark General Callback pending status as false*/
gpphLibContext->status.GenCb_pending_status = FALSE;
/* Check the shutdown is called during the lower layer Connect in process,
If yes call shutdown call and return NFCSTATUS_SHUTDOWN */
if((eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state))
{
phLibNfc_Pending_Shutdown();
Connect_status = NFCSTATUS_SHUTDOWN;
}
else if(PHNFCSTATUS(status)==NFCSTATUS_SUCCESS)
{
/* Copy the Remote device address as connected handle*/
gpphLibContext->Connected_handle =(uint32_t) pRmtdev_info;
/* Update the state to connected and return status as SUCCESS*/
gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect;
Connect_status = NFCSTATUS_SUCCESS;
}
else
{ /* if(PHNFCSTATUS(status)==NFCSTATUS_INVALID_REMOTE_DEVICE) */
/* If remote device is invalid return as TARGET LOST to upper layer*/
/* If error code is other than SUCCESS return NFCSTATUS_TARGET_LOST */
Connect_status = NFCSTATUS_TARGET_LOST;
gpphLibContext->Connected_handle = gpphLibContext->Prev_Connected_handle ;
}
gpphLibContext->ndef_cntx.is_ndef = CHK_NDEF_NOT_DONE;
/* Update the Current Sate*/
phLibNfc_UpdateCurState(Connect_status,(phLibNfc_LibContext_t *)pContext);
/* Call the upper layer callback*/
gpphLibContext->CBInfo.pClientConnectCb(
gpphLibContext->CBInfo.pClientConCntx,
(uint32_t)pRmtdev_info,
(phLibNfc_sRemoteDevInformation_t*)pRmtdev_info,
Connect_status);
}
else
{ /*exception: wrong context pointer returned*/
phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
}
return;
}
/**
* Allows to disconnect from already connected target.
*/
NFCSTATUS phLibNfc_RemoteDev_Disconnect( phLibNfc_Handle hRemoteDevice,
phLibNfc_eReleaseType_t ReleaseType,
pphLibNfc_DisconnectCallback_t pDscntCallback,
void* pContext
)
{
NFCSTATUS RetVal = NFCSTATUS_SUCCESS;
phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo=NULL;
/*Check for valid parameter*/
if((NULL == gpphLibContext) ||
(gpphLibContext->LibNfcState.cur_state
== eLibNfcHalStateShutdown))
{
RetVal = NFCSTATUS_NOT_INITIALISED;
}
else if((NULL == pContext) ||
(NULL == pDscntCallback)||(hRemoteDevice == 0))
{
RetVal= NFCSTATUS_INVALID_PARAMETER;
}
/* Check for valid state,If De initialize is called then
return NFCSTATUS_SHUTDOWN */
else if(gpphLibContext->LibNfcState.next_state
== eLibNfcHalStateShutdown)
{
RetVal= NFCSTATUS_SHUTDOWN;
}
else if(gpphLibContext->Connected_handle==0)
{
RetVal=NFCSTATUS_TARGET_NOT_CONNECTED;
}
/* The given handle is not the connected handle return NFCSTATUS_INVALID_HANDLE*/
else if(hRemoteDevice != gpphLibContext->Connected_handle )
{
RetVal=NFCSTATUS_INVALID_HANDLE;
}
else
{
if((eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
||((gpphLibContext->sSeContext.eActivatedMode == phLibNfc_SE_ActModeWired)&&
(ReleaseType != NFC_SMARTMX_RELEASE))
||((gpphLibContext->sSeContext.eActivatedMode != phLibNfc_SE_ActModeWired)&&
(ReleaseType == NFC_SMARTMX_RELEASE)))
{ /* Previous disconnect callback is pending */
RetVal = NFCSTATUS_REJECTED;
}
#ifndef LLCP_CHANGES
else if(eLibNfcHalStateTransaction == gpphLibContext->LibNfcState.next_state)
{ /* Previous Transaction is Pending*/
RetVal = NFCSTATUS_BUSY;
PHDBG_INFO("LibNfc:Transaction is Pending");
}
#endif /* #ifdef LLCP_CHANGES */
else
{
gpphLibContext->ReleaseType = ReleaseType;
psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice;
RetVal = phHal4Nfc_Disconnect(gpphLibContext->psHwReference,
(phHal_sRemoteDevInformation_t*)psRemoteDevInfo,
gpphLibContext->ReleaseType,
(pphHal4Nfc_DiscntCallback_t)
phLibNfc_RemoteDev_Disconnect_cb,
(void *)gpphLibContext);
if( NFCSTATUS_PENDING == PHNFCSTATUS(RetVal))
{
/*Copy the upper layer Callback pointer and context*/
gpphLibContext->CBInfo.pClientDisConnectCb = pDscntCallback;
gpphLibContext->CBInfo.pClientDConCntx = pContext;
/* Mark general callback pending status as TRUE and update the state*/
gpphLibContext->status.GenCb_pending_status=TRUE;
gpphLibContext->LibNfcState.next_state = eLibNfcHalStateRelease;
}
else
{
/*If lower layer returns other than pending
(internal error codes) return NFCSTATUS_FAILED */
RetVal = NFCSTATUS_FAILED;
}
}
}
return RetVal;
}
/**
* Response callback for Remote device Disconnect.
*/
STATIC void phLibNfc_RemoteDev_Disconnect_cb(
void *context,
phHal_sRemoteDevInformation_t *reg_handle,
NFCSTATUS status
)
{
NFCSTATUS DisCnct_status = NFCSTATUS_SUCCESS;
pphLibNfc_DisconnectCallback_t pUpper_NtfCb = NULL;
void *pUpper_Context = NULL;
/* Copy the upper layer Callback and context*/
pUpper_NtfCb = gpphLibContext->CBInfo.pClientDisConnectCb;
pUpper_Context = gpphLibContext->CBInfo.pClientDConCntx;
/* Check valid context is returned or not */
if((phLibNfc_LibContext_t *)context != gpphLibContext)
{
/*exception: wrong context pointer returned*/
phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
}
else
{
/* Mark the General callback pending status FALSE */
gpphLibContext->status.GenCb_pending_status = FALSE;
gpphLibContext->CBInfo.pClientDisConnectCb = NULL;
gpphLibContext->CBInfo.pClientDConCntx = NULL;
gpphLibContext->ndef_cntx.is_ndef = CHK_NDEF_NOT_DONE;
gpphLibContext->LastTrancvSuccess = FALSE;
/*Reset Connected handle */
gpphLibContext->Connected_handle=0x0000;
/*Reset previous Connected handle */
gpphLibContext->Prev_Connected_handle = 0x0000;
if(gpphLibContext->sSeContext.eActivatedMode == phLibNfc_SE_ActModeWired)
{
gpphLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeDefault;
}
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;
}
}
/* Check DeInit is called or not */
if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
{
/*call shutdown and return status as NFCSTATUS_SHUTDOWN */
phLibNfc_Pending_Shutdown();
DisCnct_status = NFCSTATUS_SHUTDOWN;
}
else if(NFCSTATUS_SUCCESS == status)
{
DisCnct_status = NFCSTATUS_SUCCESS;
gpphLibContext->LibNfcState.next_state = eLibNfcHalStateRelease;
}
else
{
DisCnct_status = NFCSTATUS_FAILED;
phLibNfc_UpdateCurState(DisCnct_status,(phLibNfc_LibContext_t *)context);
}
/* Call the upper layer Callback */
(*pUpper_NtfCb)(pUpper_Context,
(uint32_t)reg_handle,
DisCnct_status);
return;
}
/**
* This interface allows to perform Read/write operation on remote device.
*/
NFCSTATUS
phLibNfc_RemoteDev_Transceive(phLibNfc_Handle hRemoteDevice,
phLibNfc_sTransceiveInfo_t* psTransceiveInfo,
pphLibNfc_TransceiveCallback_t pTransceive_RspCb,
void* pContext
)
{
NFCSTATUS RetVal = NFCSTATUS_SUCCESS;
/*Check for valid parameter */
if((NULL == gpphLibContext) ||
(gpphLibContext->LibNfcState.cur_state
== eLibNfcHalStateShutdown))
{
RetVal = NFCSTATUS_NOT_INITIALISED;
}
else if((NULL == psTransceiveInfo)
|| (NULL == pTransceive_RspCb)
|| (NULL == (void *)hRemoteDevice)
|| (NULL == psTransceiveInfo->sRecvData.buffer)
|| (NULL == psTransceiveInfo->sSendData.buffer)
|| (NULL == pContext))
{
RetVal= NFCSTATUS_INVALID_PARAMETER;
}
/* Check the state for DeInit is called or not,if yes return NFCSTATUS_SHUTDOWN*/
else if(gpphLibContext->LibNfcState.next_state
== eLibNfcHalStateShutdown)
{
RetVal= NFCSTATUS_SHUTDOWN;
}/* If there is no handle connected return NFCSTATUS_TARGET_NOT_CONNECTED*/
else if(gpphLibContext->Connected_handle==0)
{
RetVal=NFCSTATUS_TARGET_NOT_CONNECTED;
}/* If the given handle is not the connected handle return NFCSTATUS_INVALID_HANDLE */
else if(gpphLibContext->Connected_handle!= hRemoteDevice )
{
RetVal=NFCSTATUS_INVALID_HANDLE;
} /*If the transceive is called before finishing the previous transceive function
return NFCSTATUS_REJECTED */
else if((eLibNfcHalStateTransaction ==
gpphLibContext->LibNfcState.next_state)
||(phHal_eNfcIP1_Initiator==
((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType))
{
RetVal = NFCSTATUS_REJECTED;
}
#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->ndef_cntx.eLast_Call = RawTrans;
(void)memcpy((void *)(gpphLibContext->psTransInfo),
(void *)psTransceiveInfo,
sizeof(phLibNfc_sTransceiveInfo_t));
/* Check the given Mifare command is supported or not ,
If not return NFCSTATUS_COMMAND_NOT_SUPPORTED */
if( (((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType ==
phHal_eMifare_PICC)&&
( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareRaw ) &&
( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareAuthentA ) &&
( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareAuthentB ) &&
( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareRead16 ) &&
( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareRead ) &&
( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareWrite16 ) &&
( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareWrite4 ) &&
( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareDec ) &&
( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareTransfer ) &&
( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareRestore ) &&
( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareReadSector ) &&
( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareWriteSector ))
{
RetVal = NFCSTATUS_COMMAND_NOT_SUPPORTED;
}
if(eLibNfcHalStatePresenceChk !=
gpphLibContext->LibNfcState.next_state)
{
PHDBG_INFO("LibNfc:Transceive In Progress");
if((((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType ==
phHal_eMifare_PICC) && (((phHal_sRemoteDevInformation_t*)
hRemoteDevice)->RemoteDevInfo.Iso14443A_Info.Sak != 0)&&
(phHal_eMifareAuthentA == gpphLibContext->psTransInfo->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 = psTransceiveInfo->addr;
gpphLibContext->psBufferedAuth->cmd = psTransceiveInfo->cmd;
gpphLibContext->psBufferedAuth->sSendData.length
= psTransceiveInfo->sSendData.length;
gpphLibContext->psBufferedAuth->sRecvData.length
= psTransceiveInfo->sRecvData.length;
gpphLibContext->psBufferedAuth->sSendData.buffer
= (uint8_t *)
phOsalNfc_GetMemory(
gpphLibContext->psTransInfo->sSendData.length);
(void)memcpy((void *)
(gpphLibContext->psBufferedAuth->sSendData.buffer),
(void *)psTransceiveInfo->sSendData.buffer,
psTransceiveInfo->sSendData.length);
gpphLibContext->psBufferedAuth->sRecvData.buffer
= (uint8_t *)
phOsalNfc_GetMemory(
gpphLibContext->psTransInfo->sRecvData.length);
}
/*Call the lower layer Transceive function */
RetVal = phHal4Nfc_Transceive( gpphLibContext->psHwReference,
(phHal_sTransceiveInfo_t*)gpphLibContext->psTransInfo,
(phLibNfc_sRemoteDevInformation_t*)hRemoteDevice,
(pphHal4Nfc_TransceiveCallback_t)
phLibNfc_RemoteDev_Transceive_Cb,
(void* )gpphLibContext);
if(PHNFCSTATUS(RetVal) == NFCSTATUS_PENDING)
{
/* Copy the upper layer callback pointer and context */
gpphLibContext->CBInfo.pClientTransceiveCb = pTransceive_RspCb;
gpphLibContext->CBInfo.pClientTranseCntx = pContext;
/* Mark the General callback pending status is TRUE */
gpphLibContext->status.GenCb_pending_status = TRUE;
/*Transceive is in Progress-Used in Release API*/
/*Update the state machine*/
gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction;
}
}
else
{
gpphLibContext->status.GenCb_pending_status = FALSE;
RetVal = NFCSTATUS_FAILED;
}
}
return RetVal;
}
/**
* Response for Remote device transceive.
*/
STATIC
void phLibNfc_RemoteDev_Transceive_Cb(void *context,
phHal_sRemoteDevInformation_t *pRmtdev_info,
phNfc_sData_t *response,
NFCSTATUS status
)
{
NFCSTATUS trans_status = NFCSTATUS_SUCCESS;
phNfc_sData_t *trans_resp= NULL;
void *pUpper_Context = NULL;
pphLibNfc_TransceiveCallback_t pUpper_TagNtfCb =
gpphLibContext->CBInfo.pClientTransceiveCb;
/*Check valid context is returned or not */
if((phLibNfc_LibContext_t *)context == gpphLibContext)
{
trans_resp = &gpphLibContext->psTransInfo->sRecvData;
pUpper_Context = gpphLibContext->CBInfo.pClientTranseCntx;
gpphLibContext->status.GenCb_pending_status = FALSE;
/*If DeInit is called during the transceive,
call the shutdown and return NFCSTATUS_SHUTDOWN*/
if(gpphLibContext->LibNfcState.next_state
== eLibNfcHalStateShutdown)
{
phLibNfc_Pending_Shutdown();
trans_status = NFCSTATUS_SHUTDOWN;
}
/* If Disconnect is called return NFCSTATUS_ABORTED */
else if(eLibNfcHalStateRelease ==
gpphLibContext->LibNfcState.next_state)
{
trans_status = NFCSTATUS_ABORTED;
}
/* If the received lower layer status is not SUCCESS return NFCSTATUS_FAILED */
else if( NFCSTATUS_SUCCESS == status)
{
trans_status = NFCSTATUS_SUCCESS;
}
else if((PHNFCSTATUS(status) != NFCSTATUS_SUCCESS) &&
(phHal_eMifare_PICC == pRmtdev_info->RemDevType) &&
(0x00 != pRmtdev_info->RemoteDevInfo.Iso14443A_Info.Sak))
{
gpphLibContext->LastTrancvSuccess = FALSE;
trans_status = NFCSTATUS_FAILED;
/* card type is mifare 1k/4k, then reconnect */
trans_status = phHal4Nfc_Connect(gpphLibContext->psHwReference,
pRmtdev_info,
(pphHal4Nfc_ConnectCallback_t)
phLibNfc_Reconnect_Mifare_Cb,
(void *)gpphLibContext);
}
else if ((PHNFCSTATUS(status) == PN544_IO_TIMEOUT_RESPONSE) ||
(PHNFCSTATUS(status) == NFCSTATUS_RF_TIMEOUT))
{
// 0x89, 0x09 HCI response values from PN544 indicate timeout
trans_status = NFCSTATUS_TARGET_LOST;
}
else
{
// PN544 did get some reply from tag, just not valid
trans_status = NFCSTATUS_FAILED;
}
/*Update the state machine */
phLibNfc_UpdateCurState(status,gpphLibContext);
gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect;
if(NFCSTATUS_PENDING != trans_status)
{
/* Tranceive over */
PHDBG_INFO("LibNfc:TXRX Callback-Update the Transceive responce");
if (NULL != pUpper_TagNtfCb)
{
if(trans_status == NFCSTATUS_SUCCESS)
{
gpphLibContext->LastTrancvSuccess = TRUE;
pUpper_Context = gpphLibContext->CBInfo.pClientTranseCntx;
trans_resp->buffer = response->buffer;
trans_resp->length = response->length;
/* Notify the upper layer */
PHDBG_INFO("LibNfc:Transceive Complete");
/* Notify the Transceive Completion to upper layer */
gpphLibContext->CBInfo.pClientTransceiveCb(pUpper_Context,
(uint32_t)pRmtdev_info,
trans_resp,
trans_status);
}
else
{
gpphLibContext->LastTrancvSuccess = FALSE;
pUpper_Context = gpphLibContext->CBInfo.pClientTranseCntx;
trans_resp->length = 0;
/* Notify the upper layer */
PHDBG_INFO("LibNfc:Transceive Complete");
/* Notify the Transceive Completion to upper layer */
gpphLibContext->CBInfo.pClientTransceiveCb(pUpper_Context,
(uint32_t)pRmtdev_info,
trans_resp,
trans_status);
}
}
}
}
else
{ /*exception: wrong context pointer returned*/
phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
}
return;
}
/**
* Interface to configure P2P configurations.
*/
NFCSTATUS
phLibNfc_Mgt_SetP2P_ConfigParams(phLibNfc_sNfcIPCfg_t* pConfigInfo,
pphLibNfc_RspCb_t pConfigRspCb,
void* pContext
)
{
NFCSTATUS RetVal = NFCSTATUS_FAILED;
/* LibNfc Initialized or not */
if((NULL == gpphLibContext)||
(gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
{
RetVal = NFCSTATUS_NOT_INITIALISED;
}/* Check for valid parameters */
else if((NULL == pConfigInfo) || (NULL == pConfigRspCb)
|| (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 callback is pending */
RetVal = NFCSTATUS_BUSY;
}
else
{
if(eLibNfcHalStatePresenceChk !=
gpphLibContext->LibNfcState.next_state)
{
phHal_uConfig_t uConfig;
/* copy General bytes of Max length = 48 bytes */
(void)memcpy((void *)&(uConfig.nfcIPConfig.generalBytes),
(void *)pConfigInfo->generalBytes,
pConfigInfo->generalBytesLength);
/* also copy the General Bytes length*/
uConfig.nfcIPConfig.generalBytesLength = pConfigInfo->generalBytesLength;
RetVal = phHal4Nfc_ConfigParameters(
gpphLibContext->psHwReference,
NFC_P2P_CONFIG,
&uConfig,
phLibNfc_Mgt_SetP2P_ConfigParams_Cb,
(void *)gpphLibContext
);
}
else
{
gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb= NULL;
RetVal = NFCSTATUS_PENDING;
}
if(NFCSTATUS_PENDING == RetVal)
{
/* save the context and callback for later use */
gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb = pConfigRspCb;
gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx = pContext;
gpphLibContext->status.GenCb_pending_status=TRUE;
/* Next state is configured */
gpphLibContext->LibNfcState.next_state =eLibNfcHalStateConfigReady;
}
else
{
RetVal = NFCSTATUS_FAILED;
}
}
return RetVal;
}
/**
* Response callback for P2P configurations.
*/
STATIC void phLibNfc_Mgt_SetP2P_ConfigParams_Cb(void *context,
NFCSTATUS status)
{
pphLibNfc_RspCb_t pClientCb=NULL;
void *pUpperLayerContext=NULL;
/* Check for the context returned by below layer */
if((phLibNfc_LibContext_t *)context != gpphLibContext)
{ /*wrong context returned*/
phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
}
else
{
if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
{ /*shutdown called before completion of this api allow
shutdown to happen */
phLibNfc_Pending_Shutdown();
status = NFCSTATUS_SHUTDOWN;
}
else
{
gpphLibContext->status.GenCb_pending_status = FALSE;
if(NFCSTATUS_SUCCESS != status)
{
status = NFCSTATUS_FAILED;
}
else
{
status = NFCSTATUS_SUCCESS;
}
}
/*update the current state */
phLibNfc_UpdateCurState(status,gpphLibContext);
pClientCb = gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb;
pUpperLayerContext = gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx;
gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb = NULL;
gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx = NULL;
if (NULL != pClientCb)
{
/* Notify to upper layer status of configure operation */
pClientCb(pUpperLayerContext, status);
}
}
return;
}