diff options
author | Nick Pelly <npelly@google.com> | 2010-09-23 12:47:58 -0700 |
---|---|---|
committer | Nick Pelly <npelly@google.com> | 2010-09-23 13:53:18 -0700 |
commit | 5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a (patch) | |
tree | 190f9251c6db03d3550ec7f30b51a2561c01d9cf /src/phLibNfc_initiator.c | |
parent | 4ff7c86a2c706b150078274455406f1b04966e1a (diff) | |
download | external_libnfc-nxp-5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a.zip external_libnfc-nxp-5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a.tar.gz external_libnfc-nxp-5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a.tar.bz2 |
Initial libnfc checkin
Source: Trusted_NFC_Device_Host_AA03.01e02_google.zip code drop (23-Sep-2010)
Change-Id: Ie47f18423f949a8d3e0815d13f55c814312add24
Signed-off-by: Nick Pelly <npelly@google.com>
Diffstat (limited to 'src/phLibNfc_initiator.c')
-rw-r--r-- | src/phLibNfc_initiator.c | 1154 |
1 files changed, 1154 insertions, 0 deletions
diff --git a/src/phLibNfc_initiator.c b/src/phLibNfc_initiator.c new file mode 100644 index 0000000..5cd14bb --- /dev/null +++ b/src/phLibNfc_initiator.c @@ -0,0 +1,1154 @@ +/* + * 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 ********************************** +*/ + + + +/* +*************************** 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 + ); + +/*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; +} + + +/** +* 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 + { + 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->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; +} +/** +* 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) + { + + /* 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->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; + } + else if(eLibNfcHalStateTransaction == gpphLibContext->LibNfcState.next_state) + { /* Previous Transaction is Pending*/ + RetVal = NFCSTATUS_BUSY; + PHDBG_INFO("LibNfc:Transaction is Pending"); + } + 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; + 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; + } + 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)) + { + 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 + { + trans_status = NFCSTATUS_TARGET_LOST; + } + /*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; +} + + + + + + + + + + |