| /* |
| * 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; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |