summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--inc/phNfcConfig.h2
-rw-r--r--src/phHal4Nfc_Reader.c36
-rw-r--r--src/phLibNfc.h69
-rw-r--r--src/phLibNfc_initiator.c168
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
*/