diff options
author | Martijn Coenen <martijn.coenen@nxp.com> | 2010-12-16 16:54:00 +0100 |
---|---|---|
committer | Jeff Hamilton <jham@android.com> | 2010-12-16 14:02:04 -0600 |
commit | d75796b759f9baac8facf22f1b6c6bcfbc51161e (patch) | |
tree | cd2557b01e06ddedcfb7eed87e727b0b7a103a9d | |
parent | 04f25b3ab4ed13edb3ffc8e7354bca9f7bc60b44 (diff) | |
download | external_libnfc-nxp-d75796b759f9baac8facf22f1b6c6bcfbc51161e.zip external_libnfc-nxp-d75796b759f9baac8facf22f1b6c6bcfbc51161e.tar.gz external_libnfc-nxp-d75796b759f9baac8facf22f1b6c6bcfbc51161e.tar.bz2 |
Add support for connecting to different handles on the same tag.
This is needed for proper multi-protocol tag support.
(Before this required a restart of the polling loop).
Change-Id: If61da437cda40d82bdbacf5a01ea4c585c7a5be9
-rw-r--r-- | inc/phNfcConfig.h | 2 | ||||
-rw-r--r-- | src/phHal4Nfc_Reader.c | 36 | ||||
-rw-r--r-- | src/phLibNfc.h | 69 | ||||
-rw-r--r-- | src/phLibNfc_initiator.c | 168 |
4 files changed, 275 insertions, 0 deletions
diff --git a/inc/phNfcConfig.h b/inc/phNfcConfig.h index 376c75c..e733557 100644 --- a/inc/phNfcConfig.h +++ b/inc/phNfcConfig.h @@ -362,6 +362,8 @@ * to allow the UICC Communication */ #define HOST_WHITELIST +/**< Support reconnecting to a different handle on the same tag */ +#define RECONNECT_SUPPORT /**< Macro to Enable the Card Emulation Feature */ /* #define HOST_EMULATION */ diff --git a/src/phHal4Nfc_Reader.c b/src/phHal4Nfc_Reader.c index d74e5e9..b767858 100644 --- a/src/phHal4Nfc_Reader.c +++ b/src/phHal4Nfc_Reader.c @@ -188,6 +188,42 @@ NFCSTATUS phHal4Nfc_Connect( ); Hal4Ctxt->Hal4NextState = eHal4StateTargetActivate; } +#ifdef RECONNECT_SUPPORT + else if (psRemoteDevInfo != + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) + { + phHal_sRemoteDevInformation_t *ps_store_connected_device = + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice; + + RemoteDevCount = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; + + while (0 != RemoteDevCount) + { + RemoteDevCount--; + /*Check if handle provided by upper layer matches with any + remote device in the list*/ + if(psRemoteDevInfo == (Hal4Ctxt->rem_dev_list[RemoteDevCount])) + { + break; + } + }/*End of while*/ + + if (ps_store_connected_device == + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) + { + RetStatus = phHciNfc_Reactivate (Hal4Ctxt->psHciHandle, + (void *)psHwReference, + psRemoteDevInfo); + + if (NFCSTATUS_PENDING == RetStatus) + { + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice = + Hal4Ctxt->rem_dev_list[RemoteDevCount]; + Hal4Ctxt->Hal4NextState = eHal4StateTargetActivate; + } + } + } +#endif /* #ifdef RECONNECT_SUPPORT */ else if(NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) { /*Wrong state to issue connect*/ diff --git a/src/phLibNfc.h b/src/phLibNfc.h index e3346a0..f96b86d 100644 --- a/src/phLibNfc.h +++ b/src/phLibNfc.h @@ -37,9 +37,11 @@ #include <phLibNfcStatus.h> #include <phFriNfc_NdefRecord.h> #include <phNfcLlcpTypes.h> +#include <phNfcConfig.h> #ifdef ANDROID #include <string.h> #endif + /*! *\def PHLIBNFC_MAXNO_OF_SE *Defines maximum no of secured elements supported by PN544. @@ -1362,6 +1364,73 @@ NFCSTATUS phLibNfc_RemoteDev_Connect(phLibNfc_Handle hRemoteDevic void* pContext ); +#ifdef RECONNECT_SUPPORT + +/** +* \ingroup grp_lib_nfc +* \brief This function is used to to connect to NEXT Remote Device. +* +* This function is called only if there are more than one remote device is detected. +* Once notification handler notified sucessfully discovered targets will be available in +* \ref phLibNfc_RemoteDevList_t .Remote device list contains valid handles for discovered +* targets .Using this interface LibNfc client can connect to one out of 'n' discovered targets. +* A new session is started after connect operation is successful. +* Similarly, if the user wants to connect to another handle. Libnfc client can select the handle and +* the previously connected device is replaced by present handle. The session ends with a +* successful disconnect operation. +* Re-Connect operation on an already connected tag Reactivates the Tag. This Feature is not +* Valid for Jewel/Topaz Tags ,and hence a second re-connect if issued +* without disconnecting a Jewel/Topaz tag always Fails. +* +* \note :In case multiple targets discovered LibNfc client can re-connect to only one target. +* +* \param[in] hRemoteDevice Handle of the target device obtained during discovery process. +* +* \param[in] pNotifyReConnect_RspCb Client response callback to be to be +* notified to indicate status of the request. +* +* \param[in] pContext Client context which will be included in +* callback when the request is completed. +* +*\retval NFCSTATUS_PENDING Request initiated, result will be informed via +* callback. +*\retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters +* could not be properly interpreted. +*\retval NFCSTATUS_TARGET_LOST Indicates target is lost. +*\retval NFSCSTATUS_SHUTDOWN shutdown in progress. +*\retval NFCSTATUS_NOT_INITIALISED Indicates stack is not yet initialized. +*\retval NFCSTATUS_INVALID_HANDLE Target handle is invalid. +* +*\retval NFCSTATUS_FAILED Request failed. +* +* +*\msc +*LibNfcClient,LibNfc; +*LibNfcClient=>LibNfc [label="phLibNfc_Mgt_Initialize()",URL="\ref phLibNfc_Mgt_Initialize"]; +*LibNfcClient<-LibNfc [label="pInitCb()",URL="\ref pphLibNfc_RspCb_t()"]; +*LibNfcClient=>LibNfc [label="phLibNfc_RemoteDev_NtfRegister()",URL="\ref phLibNfc_RemoteDev_NtfRegister"]; +*LibNfcClient<<LibNfc [label="NFCSTATUS_SUCCESS"]; +*LibNfcClient=>LibNfc [label="phLibNfc_Mgt_configureDiscovery()",URL="\ref phLibNfc_Mgt_ConfigureDiscovery"]; +*LibNfcClient<-LibNfc [label="pConfigDiscovery_RspCb",URL="\ref pphLibNfc_RspCb_t"]; +*--- [label="Now Present multiple protocol Tag to be discovered"]; +*LibNfcClient<-LibNfc [label="pNotificationHandler",URL="\ref phLibNfc_NtfRegister_RspCb_t"]; +*--- [label="TWO remote device information is received, So connect with one handle"]; +*LibNfcClient=>LibNfc [label="phLibNfc_RemoteDev_Connect()",URL="\ref phLibNfc_RemoteDev_Connect"]; +*LibNfcClient<-LibNfc [label="pNotifyConnect_RspCb",URL="\ref pphLibNfc_ConnectCallback_t"]; +*--- [label="Connect is successful, so transact using this handle. Now if user wants to switch to another handle then call Reconnect "]; +*LibNfcClient=>LibNfc [label="phLibNfc_RemoteDev_ReConnect()",URL="\ref phLibNfc_RemoteDev_ReConnect"]; +*LibNfcClient<-LibNfc [label="pNotifyReConnect_RspCb",URL="\ref pphLibNfc_ConnectCallback_t"]; +* +*\endmsc +*/ +NFCSTATUS +phLibNfc_RemoteDev_ReConnect ( + phLibNfc_Handle hRemoteDevice, + pphLibNfc_ConnectCallback_t pNotifyReConnect_RspCb, + void *pContext); + +#endif /* #ifdef RECONNECT_SUPPORT */ + /** * \ingroup grp_lib_nfc * \brief This interface allows to perform Read/write operation on remote device. diff --git a/src/phLibNfc_initiator.c b/src/phLibNfc_initiator.c index d599465..d93d5f6 100644 --- a/src/phLibNfc_initiator.c +++ b/src/phLibNfc_initiator.c @@ -76,6 +76,14 @@ STATIC void phLibNfc_RemoteDev_Connect_Cb( 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, @@ -473,6 +481,91 @@ NFCSTATUS phLibNfc_RemoteDev_NtfUnregister(void) 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->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 @@ -517,6 +610,11 @@ NFCSTATUS phLibNfc_RemoteDev_Connect( { RetVal= NFCSTATUS_INVALID_HANDLE; } + else if ((hRemoteDevice != gpphLibContext->Connected_handle) + && (0 != gpphLibContext->Connected_handle)) + { + RetVal = NFCSTATUS_FAILED; + } else { psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice; @@ -550,6 +648,76 @@ NFCSTATUS phLibNfc_RemoteDev_Connect( } 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 */ |