summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--inc/phNfcLlcpTypes.h3
-rw-r--r--src/phFriNfc_Llcp.h23
-rw-r--r--src/phFriNfc_LlcpTransport.c1008
-rw-r--r--src/phFriNfc_LlcpTransport.h98
-rw-r--r--src/phFriNfc_LlcpTransport_Connection.c716
-rw-r--r--src/phFriNfc_LlcpTransport_Connection.h7
-rw-r--r--src/phFriNfc_LlcpTransport_Connectionless.c71
-rw-r--r--src/phFriNfc_LlcpTransport_Connectionless.h4
-rw-r--r--src/phFriNfc_LlcpUtils.c46
-rw-r--r--src/phFriNfc_LlcpUtils.h6
-rw-r--r--src/phHal4Nfc_P2P.c19
-rw-r--r--src/phHal4Nfc_Reader.c10
-rw-r--r--src/phHciNfc_NfcIPMgmt.c24
-rw-r--r--src/phHciNfc_NfcIPMgmt.h2
-rw-r--r--src/phLibNfc.h52
-rw-r--r--src/phLibNfc_Internal.h8
-rw-r--r--src/phLibNfc_llcp.c74
17 files changed, 1565 insertions, 606 deletions
diff --git a/inc/phNfcLlcpTypes.h b/inc/phNfcLlcpTypes.h
index 2954d00..84c58cd 100644
--- a/inc/phNfcLlcpTypes.h
+++ b/inc/phNfcLlcpTypes.h
@@ -44,6 +44,8 @@
#define PHFRINFC_LLCP_RW_DEFAULT 1 /**< Default RW value (in frames).*/
#define PHFRINFC_LLCP_OPTION_DEFAULT 0 /**< Default OPTION value (in frames).*/
#define PHFRINFC_LLCP_MIUX_DEFAULT 0 /**< Default MIUX value (in bytes) */
+#define PHFRINFC_LLCP_MIUX_MAX 0x7FF /**< Max MIUX value (in bytes) */
+#define PHFRINFC_LLCP_PDU_HEADER_MAX 3 /**< Max size of PDU header (in bytes) */
#define PHFRINFC_LLCP_SN_MAX_LENGTH 255 /**< Max length value for the Service Name */
#define PHFRINFC_LLCP_RW_MAX 15 /**< Max RW value (in frames).*/
/*@}*/
@@ -56,6 +58,7 @@
*/
/*@{*/
#define PHFRINFC_LLCP_NB_SOCKET_MAX 10 /**< Max.number of simultaneous sockets */
+#define PHFRINFC_LLCP_SNL_RESPONSE_MAX 256 /**< Max.number of simultaneous discovery requests */
/*@}*/
/**
diff --git a/src/phFriNfc_Llcp.h b/src/phFriNfc_Llcp.h
index 287f9f9..fb26d6a 100644
--- a/src/phFriNfc_Llcp.h
+++ b/src/phFriNfc_Llcp.h
@@ -83,7 +83,7 @@ extern char phOsalNfc_DbgTraceBuffer[];
*/
/*@{*/
#define PHFRINFC_LLCP_VERSION_MAJOR 0x01 /**< Major number of local LLCP version.*/
-#define PHFRINFC_LLCP_VERSION_MINOR 0x00 /**< Minor number of local LLCP version.*/
+#define PHFRINFC_LLCP_VERSION_MINOR 0x01 /**< Minor number of local LLCP version.*/
#define PHFRINFC_LLCP_VERSION ((PHFRINFC_LLCP_VERSION_MAJOR << 4) | PHFRINFC_LLCP_VERSION_MINOR) /**< Local LLCP version.*/
/*@}*/
@@ -97,17 +97,17 @@ extern char phOsalNfc_DbgTraceBuffer[];
#define PHFRINFC_LLCP_PTYPE_AGF 0x02 /**< AGgregated Frame.*/
#define PHFRINFC_LLCP_PTYPE_UI 0x03 /**< Unnumbered Information.*/
#define PHFRINFC_LLCP_PTYPE_CONNECT 0x04 /**< Connect.*/
-#define PHFRINFC_LLCP_PTYPE_DISC 0x05 /**< Didconnect.*/
+#define PHFRINFC_LLCP_PTYPE_DISC 0x05 /**< Disconnect.*/
#define PHFRINFC_LLCP_PTYPE_CC 0x06 /**< Connection Complete.*/
#define PHFRINFC_LLCP_PTYPE_DM 0x07 /**< Disconnected Mode.*/
#define PHFRINFC_LLCP_PTYPE_FRMR 0x08 /**< FRaMe Reject.*/
-#define PHFRINFC_LLCP_PTYPE_RESERVED1 0x09 /**< Reserved.*/
-#define PHFRINFC_LLCP_PTYPE_RESERVED2 0x0A /**< Reserved.*/
-#define PHFRINFC_LLCP_PTYPE_RESERVED3 0x0B /**< Reserved.*/
+#define PHFRINFC_LLCP_PTYPE_SNL 0x09 /**< Service Name Lookup.*/
+#define PHFRINFC_LLCP_PTYPE_RESERVED1 0x0A /**< Reserved.*/
+#define PHFRINFC_LLCP_PTYPE_RESERVED2 0x0B /**< Reserved.*/
#define PHFRINFC_LLCP_PTYPE_I 0x0C /**< Information.*/
#define PHFRINFC_LLCP_PTYPE_RR 0x0D /**< Receive Ready.*/
#define PHFRINFC_LLCP_PTYPE_RNR 0x0E /**< Receive Not Ready.*/
-#define PHFRINFC_LLCP_PTYPE_RESERVED4 0x0F /**< Reserved.*/
+#define PHFRINFC_LLCP_PTYPE_RESERVED3 0x0F /**< Reserved.*/
/*@}*/
/**
@@ -122,6 +122,15 @@ extern char phOsalNfc_DbgTraceBuffer[];
#define PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST 0x20 /**< First SAP number from SDP-unavertised SAP range.*/
#define PHFRINFC_LLCP_SAP_NUMBER 0x40 /**< Number of possible SAP values (also first invalid value).*/
#define PHFRINFC_LLCP_SAP_DEFAULT 0xFF /**< Default number when a socket is created or reset */
+#define PHFRINFC_LLCP_SDP_ADVERTISED_NB 0x10 /**< Number of SDP advertised SAP slots */
+/*@}*/
+
+/**
+ * \name LLCP well-known SAPs.
+ *
+ */
+ /*@{*/
+#define PHFRINFC_LLCP_SERVICENAME_SDP "urn:nfc:sn:sdp" /**< Service Discovery Protocol name.*/
/*@}*/
/**
@@ -158,6 +167,8 @@ extern char phOsalNfc_DbgTraceBuffer[];
#define PHFRINFC_LLCP_TLV_TYPE_RW 0x05 /**< \internal RW parameter Type code.*/
#define PHFRINFC_LLCP_TLV_TYPE_SN 0x06 /**< \internal SN parameter Type code.*/
#define PHFRINFC_LLCP_TLV_TYPE_OPT 0x07 /**< \internal OPT parameter Type code.*/
+#define PHFRINFC_LLCP_TLV_TYPE_SDREQ 0x08 /**< \internal SDREQ parameter Type code.*/
+#define PHFRINFC_LLCP_TLV_TYPE_SDRES 0x09 /**< \internal SDRES parameter Type code.*/
/*@}*/
/**
diff --git a/src/phFriNfc_LlcpTransport.c b/src/phFriNfc_LlcpTransport.c
index 960a33a..158dbc2 100644
--- a/src/phFriNfc_LlcpTransport.c
+++ b/src/phFriNfc_LlcpTransport.c
@@ -37,15 +37,50 @@
/* Check if (a <= x < b) */
#define IS_BETWEEN(x, a, b) (((x)>=(a)) && ((x)<(b)))
+static NFCSTATUS phFriNfc_LlcpTransport_RegisterName(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket,
+ uint8_t nSap,
+ phNfc_sData_t *psServiceName);
-static NFCSTATUS phFriNfc_LlcpTransport_AutoBind(phFriNfc_LlcpTransport_Socket_t *pSocket)
+static NFCSTATUS phFriNfc_LlcpTransport_DiscoverServicesEx(phFriNfc_LlcpTransport_t *psTransport);
+
+static void phFriNfc_LlcpTransport_Send_CB(void *pContext,
+ NFCSTATUS status);
+
+static NFCSTATUS phFriNfc_LlcpTransport_GetFreeSap(phFriNfc_LlcpTransport_t * psTransport, phNfc_sData_t *psServiceName, uint8_t * pnSap)
{
uint8_t i;
uint8_t sap;
- phFriNfc_LlcpTransport_Socket_t* pSocketTable = pSocket->psTransport->pSocketTable;
+ uint8_t min_sap_range, max_sap_range;
+ phFriNfc_LlcpTransport_Socket_t* pSocketTable = psTransport->pSocketTable;
+
+ /* Calculate authorized SAP range */
+ if ((psServiceName != NULL) && (psServiceName->length > 0))
+ {
+ /* Make sure that we will return the same SAP if service name was already used in the past */
+ for(i=0 ; i<PHFRINFC_LLCP_SDP_ADVERTISED_NB ; i++)
+ {
+ if((psTransport->pCachedServiceNames[i].sServiceName.length > 0) &&
+ (memcmp(psTransport->pCachedServiceNames[i].sServiceName.buffer, psServiceName->buffer, psServiceName->length) == 0))
+ {
+ /* Service name matched in cached service names list */
+ *pnSap = psTransport->pCachedServiceNames[i].nSap;
+ return NFCSTATUS_SUCCESS;
+ }
+ }
+
+ /* SDP advertised service */
+ min_sap_range = PHFRINFC_LLCP_SAP_SDP_ADVERTISED_FIRST;
+ max_sap_range = PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST;
+ }
+ else
+ {
+ /* Non-SDP advertised service */
+ min_sap_range = PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST;
+ max_sap_range = PHFRINFC_LLCP_SAP_NUMBER;
+ }
/* Try all possible SAPs */
- for(sap=PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST ; sap<PHFRINFC_LLCP_SAP_NUMBER ; sap++)
+ for(sap=min_sap_range ; sap<max_sap_range ; sap++)
{
/* Go through socket list to check if current SAP is in use */
for(i=0 ; i<PHFRINFC_LLCP_NB_SOCKET_MAX ; i++)
@@ -61,8 +96,7 @@ static NFCSTATUS phFriNfc_LlcpTransport_AutoBind(phFriNfc_LlcpTransport_Socket_t
if (i >= PHFRINFC_LLCP_NB_SOCKET_MAX)
{
/* No socket is using current SAP, proceed with binding */
- pSocket->socket_sSap = sap;
- pSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketBound;
+ *pnSap = sap;
return NFCSTATUS_SUCCESS;
}
}
@@ -71,6 +105,343 @@ static NFCSTATUS phFriNfc_LlcpTransport_AutoBind(phFriNfc_LlcpTransport_Socket_t
return NFCSTATUS_INSUFFICIENT_RESOURCES;
}
+static NFCSTATUS phFriNfc_LlcpTransport_EncodeSdreqTlv(phNfc_sData_t *psTlvData,
+ uint32_t *pOffset,
+ uint8_t nTid,
+ phNfc_sData_t *psServiceName)
+{
+ NFCSTATUS result;
+ uint32_t nTlvOffset = *pOffset;
+ uint32_t nTlvStartOffset = nTlvOffset;
+
+ /* Encode the TID */
+ result = phFriNfc_Llcp_EncodeTLV(psTlvData,
+ &nTlvOffset,
+ PHFRINFC_LLCP_TLV_TYPE_SDREQ,
+ 1,
+ &nTid);
+ if (result != NFCSTATUS_SUCCESS)
+ {
+ goto clean_and_return;
+ }
+
+ /* Encode the service name itself */
+ result = phFriNfc_Llcp_AppendTLV(psTlvData,
+ nTlvStartOffset,
+ &nTlvOffset,
+ psServiceName->length,
+ psServiceName->buffer);
+ if (result != NFCSTATUS_SUCCESS)
+ {
+ goto clean_and_return;
+ }
+
+clean_and_return:
+ /* Save offset if no error occured */
+ if (result == NFCSTATUS_SUCCESS)
+ {
+ *pOffset = nTlvOffset;
+ }
+
+ return result;
+}
+
+static NFCSTATUS phFriNfc_LlcpTransport_EncodeSdresTlv(phNfc_sData_t *psTlvData,
+ uint32_t *pOffset,
+ uint8_t nTid,
+ uint8_t nSap)
+{
+ NFCSTATUS result;
+ uint32_t nTlvStartOffset = *pOffset;
+
+ /* Encode the TID */
+ result = phFriNfc_Llcp_EncodeTLV(psTlvData,
+ pOffset,
+ PHFRINFC_LLCP_TLV_TYPE_SDRES,
+ 1,
+ &nTid);
+ if (result != NFCSTATUS_SUCCESS)
+ {
+ goto clean_and_return;
+ }
+
+ /* Encode the service name itself */
+ result = phFriNfc_Llcp_AppendTLV(psTlvData,
+ nTlvStartOffset,
+ pOffset,
+ 1,
+ &nSap);
+ if (result != NFCSTATUS_SUCCESS)
+ {
+ goto clean_and_return;
+ }
+
+clean_and_return:
+ /* Restore previous offset if an error occured */
+ if (result != NFCSTATUS_SUCCESS)
+ {
+ *pOffset = nTlvStartOffset;
+ }
+
+ return result;
+}
+
+static phFriNfc_LlcpTransport_Socket_t* phFriNfc_LlcpTransport_ServiceNameLoockup(phFriNfc_LlcpTransport_t *psTransport,
+ phNfc_sData_t *pServiceName)
+{
+ uint32_t index;
+ uint8_t cacheIndex;
+ phFriNfc_Llcp_CachedServiceName_t * pCachedServiceName;
+ phFriNfc_LlcpTransport_Socket_t * pSocket;
+
+ /* Search a socket with the SN */
+ for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
+ {
+ pSocket = &psTransport->pSocketTable[index];
+ /* Test if the CO socket is in Listen state or the CL socket is bound
+ and if its SN is the good one */
+ if((((pSocket->eSocket_Type == phFriNfc_LlcpTransport_eConnectionOriented)
+ && (pSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketRegistered))
+ || ((pSocket->eSocket_Type == phFriNfc_LlcpTransport_eConnectionLess)
+ && (pSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketBound)))
+ &&
+ (pServiceName->length == pSocket->sServiceName.length)
+ && !memcmp(pServiceName->buffer, pSocket->sServiceName.buffer, pServiceName->length))
+ {
+ /* Add new entry to cached service name/sap if not already in table */
+ for(cacheIndex=0;cacheIndex<PHFRINFC_LLCP_SDP_ADVERTISED_NB;cacheIndex++)
+ {
+ pCachedServiceName = &psTransport->pCachedServiceNames[cacheIndex];
+ if (pCachedServiceName->sServiceName.buffer != NULL)
+ {
+ if ((pCachedServiceName->sServiceName.length == pServiceName->length) &&
+ (memcmp(pCachedServiceName->sServiceName.buffer, pServiceName->buffer, pServiceName->length) == 0))
+ {
+ /* Already registered */
+ break;
+ }
+ }
+ else
+ {
+ /* Reached end of existing entries and not found the service name,
+ * => Add the new entry
+ */
+ pCachedServiceName->nSap = pSocket->socket_sSap;
+ pCachedServiceName->sServiceName.buffer = phOsalNfc_GetMemory(pServiceName->length);
+ if (pCachedServiceName->sServiceName.buffer == NULL)
+ {
+ /* Unable to cache this entry, so report this service as not found */
+ return NULL;
+ }
+ memcpy(pCachedServiceName->sServiceName.buffer, pServiceName->buffer, pServiceName->length);
+ pCachedServiceName->sServiceName.length = pServiceName->length;
+ break;
+ }
+ }
+
+ return pSocket;
+ }
+ }
+
+ return NULL;
+}
+
+
+static NFCSTATUS phFriNfc_LlcpTransport_DiscoveryAnswer(phFriNfc_LlcpTransport_t *psTransport)
+{
+ NFCSTATUS result = NFCSTATUS_PENDING;
+ phNfc_sData_t sInfoBuffer;
+ uint32_t nTlvOffset;
+ uint8_t index;
+ uint8_t nTid, nSap;
+
+ /* Test if a send is pending */
+ if(!psTransport->bSendPending)
+ {
+ /* Set the header */
+ psTransport->sLlcpHeader.dsap = PHFRINFC_LLCP_SAP_SDP;
+ psTransport->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_SNL;
+ psTransport->sLlcpHeader.ssap = PHFRINFC_LLCP_SAP_SDP;
+
+ /* Prepare the info buffer */
+ sInfoBuffer.buffer = psTransport->pDiscoveryBuffer;
+ sInfoBuffer.length = sizeof(psTransport->pDiscoveryBuffer);
+
+ /* Encode as many requests as possible */
+ nTlvOffset = 0;
+ for(index=0 ; index<psTransport->nDiscoveryResListSize ; index++)
+ {
+ /* Get current TID/SAP and try to encode them in SNL frame */
+ nTid = psTransport->nDiscoveryResTidList[index];
+ nSap = psTransport->nDiscoveryResSapList[index];
+ /* Encode response */
+ result = phFriNfc_LlcpTransport_EncodeSdresTlv(&sInfoBuffer,
+ &nTlvOffset,
+ nTid,
+ nSap);
+ if (result != NFCSTATUS_SUCCESS)
+ {
+ /* Impossible to fit the entire response */
+ /* TODO: support reponse framgentation */
+ break;
+ }
+ }
+
+ /* Reset list size to be able to handle a new request */
+ psTransport->nDiscoveryResListSize = 0;
+
+ /* Update buffer length to match real TLV size */
+ sInfoBuffer.length = nTlvOffset;
+
+ /* Send Pending */
+ psTransport->bSendPending = TRUE;
+
+ /* Send SNL frame */
+ result = phFriNfc_Llcp_Send(psTransport->pLlcp,
+ &psTransport->sLlcpHeader,
+ NULL,
+ &sInfoBuffer,
+ phFriNfc_LlcpTransport_Send_CB,
+ psTransport);
+ }
+ else
+ {
+ /* Impossible to send now, this function will be called again on next opportunity */
+ }
+
+ return result;
+}
+
+
+static void Handle_Discovery_IncomingFrame(phFriNfc_LlcpTransport_t *psTransport,
+ phNfc_sData_t *psData)
+{
+ NFCSTATUS result;
+ phNfc_sData_t sValue;
+ phNfc_sData_t sResponseData;
+ phNfc_sData_t sServiceName;
+ uint32_t nInTlvOffset;
+ uint8_t nType;
+ uint8_t nTid;
+ uint8_t nSap;
+ pphFriNfc_Cr_t pfSavedCb;
+ void *pfSavedContext;
+ phFriNfc_LlcpTransport_Socket_t *pSocket;
+
+
+ /* Prepare buffer */
+ sResponseData.buffer = psTransport->pDiscoveryBuffer;
+ sResponseData.length = sizeof(psTransport->pDiscoveryBuffer);
+
+ /* Parse all TLVs in frame */
+ nInTlvOffset = 0;
+ while(nInTlvOffset < psData->length)
+ {
+ result = phFriNfc_Llcp_DecodeTLV(psData,
+ &nInTlvOffset,
+ &nType,
+ &sValue );
+ switch(nType)
+ {
+ case PHFRINFC_LLCP_TLV_TYPE_SDREQ:
+ if (sValue.length < 2)
+ {
+ /* Erroneous request, ignore */
+ break;
+ }
+ /* Decode TID */
+ nTid = sValue.buffer[0];
+ /* Decode service name */
+ sServiceName.buffer = sValue.buffer + 1;
+ sServiceName.length = sValue.length - 1;
+
+ /* Handle SDP service name */
+ if((sServiceName.length == sizeof(PHFRINFC_LLCP_SERVICENAME_SDP)-1)
+ && !memcmp(sServiceName.buffer, PHFRINFC_LLCP_SERVICENAME_SDP, sServiceName.length))
+ {
+ nSap = PHFRINFC_LLCP_SAP_SDP;
+ }
+ else
+ {
+ /* Match service name in socket list */
+ pSocket = phFriNfc_LlcpTransport_ServiceNameLoockup(psTransport, &sServiceName);
+ if (pSocket != NULL)
+ {
+ nSap = pSocket->socket_sSap;
+ }
+ else
+ {
+ nSap = 0;
+ }
+ }
+
+ /* Encode response */
+ if (psTransport->nDiscoveryResListSize < PHFRINFC_LLCP_SNL_RESPONSE_MAX)
+ {
+ psTransport->nDiscoveryResSapList[psTransport->nDiscoveryResListSize] = nSap;
+ psTransport->nDiscoveryResTidList[psTransport->nDiscoveryResListSize] = nTid;
+ psTransport->nDiscoveryResListSize++;
+ }
+ else
+ {
+ /* Remote peer is sending more than max. allowed requests (max. 256
+ different TID values), drop invalid requests to avoid buffer overflow
+ */
+ }
+ break;
+
+ case PHFRINFC_LLCP_TLV_TYPE_SDRES:
+ if (psTransport->pfDiscover_Cb == NULL)
+ {
+ /* Ignore response when no requests are pending */
+ break;
+ }
+ if (sValue.length != 2)
+ {
+ /* Erroneous response, ignore it */
+ break;
+ }
+ /* Decode TID and SAP */
+ nTid = sValue.buffer[0];
+ if (nTid >= psTransport->nDiscoveryListSize)
+ {
+ /* Unkown TID, ignore it */
+ break;
+ }
+ nSap = sValue.buffer[1];
+ /* Save response */
+ psTransport->pnDiscoverySapList[nTid] = nSap;
+ /* Update response counter */
+ psTransport->nDiscoveryResOffset++;
+ break;
+
+ default:
+ /* Ignored */
+ break;
+ }
+ }
+
+ /* If discovery requests have been received, send response */
+ if (psTransport->nDiscoveryResListSize > 0)
+ {
+ phFriNfc_LlcpTransport_DiscoveryAnswer(psTransport);
+ }
+
+ /* If all discovery responses have been received, trigger callback (if any) */
+ if ((psTransport->pfDiscover_Cb != NULL) &&
+ (psTransport->nDiscoveryResOffset >= psTransport->nDiscoveryListSize))
+ {
+ pfSavedCb = psTransport->pfDiscover_Cb;
+ pfSavedContext = psTransport->pDiscoverContext;
+
+ psTransport->pfDiscover_Cb = NULL;
+ psTransport->pDiscoverContext = NULL;
+
+ pfSavedCb(pfSavedContext, NFCSTATUS_SUCCESS);
+ }
+}
+
+
/* TODO: comment function Transport recv CB */
static void phFriNfc_LlcpTransport__Recv_CB(void *pContext,
phNfc_sData_t *psData,
@@ -112,6 +483,20 @@ static void phFriNfc_LlcpTransport__Recv_CB(void *pContext,
ssap);
}break;
+ /* Service Discovery Protocol */
+ case PHFRINFC_LLCP_PTYPE_SNL:
+ {
+ if ((ssap == PHFRINFC_LLCP_SAP_SDP) && (dsap == PHFRINFC_LLCP_SAP_SDP))
+ {
+ Handle_Discovery_IncomingFrame(pLlcpTransport,
+ psData);
+ }
+ else
+ {
+ /* Ignore frame if source and destination are not the SDP service */
+ }
+ }break;
+
/* Connection oriented */
/* NOTE: forward reserved PTYPE to enable FRMR sending */
case PHFRINFC_LLCP_PTYPE_CONNECT:
@@ -125,7 +510,6 @@ static void phFriNfc_LlcpTransport__Recv_CB(void *pContext,
case PHFRINFC_LLCP_PTYPE_RESERVED1:
case PHFRINFC_LLCP_PTYPE_RESERVED2:
case PHFRINFC_LLCP_PTYPE_RESERVED3:
- case PHFRINFC_LLCP_PTYPE_RESERVED4:
{
Handle_ConnectionOriented_IncommingFrame(pLlcpTransport,
psData,
@@ -147,6 +531,115 @@ static void phFriNfc_LlcpTransport__Recv_CB(void *pContext,
}
+/* TODO: comment function Transport recv CB */
+static void phFriNfc_LlcpTransport_Send_CB(void *pContext,
+ NFCSTATUS status)
+{
+ phFriNfc_LlcpTransport_t *psTransport = (phFriNfc_LlcpTransport_t*)pContext;
+ NFCSTATUS result = NFCSTATUS_FAILED;
+ phNfc_sData_t sFrmrBuffer;
+ phFriNfc_Llcp_Send_CB_t pfSavedCb;
+ void *pSavedContext;
+ phFriNfc_LlcpTransport_Socket_t *pCurrentSocket = NULL;
+ uint8_t index;
+
+ /* 1 - Reset the FLAG send pending*/
+ psTransport->bSendPending = FALSE;
+
+ /* 2 - Handle pending error responses */
+
+ if(psTransport->bFrmrPending)
+ {
+ /* Reset FRMR pending */
+ psTransport->bFrmrPending = FALSE;
+
+ /* Send Frmr */
+ sFrmrBuffer.buffer = psTransport->FrmrInfoBuffer;
+ sFrmrBuffer.length = 0x04; /* Size of FRMR Information field */
+
+ /* Send Pending */
+ psTransport->bSendPending = TRUE;
+
+ result = phFriNfc_Llcp_Send(psTransport->pLlcp,
+ &psTransport->sLlcpHeader,
+ NULL,
+ &sFrmrBuffer,
+ phFriNfc_LlcpTransport_Send_CB,
+ psTransport);
+
+ }
+ else if(psTransport->bDmPending)
+ {
+ /* Reset DM pending */
+ psTransport->bDmPending = FALSE;
+
+ /* Send DM pending */
+ result = phFriNfc_LlcpTransport_SendDisconnectMode(psTransport,
+ psTransport->DmInfoBuffer[0],
+ psTransport->DmInfoBuffer[1],
+ psTransport->DmInfoBuffer[2]);
+ }
+
+ /* 3 - Call the original callback */
+
+ if (psTransport->pfLinkSendCb != NULL)
+ {
+ pfSavedCb = psTransport->pfLinkSendCb;
+ pSavedContext = psTransport->pLinkSendContext;
+
+ psTransport->pfLinkSendCb = NULL;
+ psTransport->pLinkSendContext = NULL;
+
+ (*pfSavedCb)(pSavedContext, status);
+ }
+
+ /* 4 - Handle pending send operations */
+
+ /* Check for pending discovery requests/responses */
+ if (psTransport->nDiscoveryResListSize > 0)
+ {
+ phFriNfc_LlcpTransport_DiscoveryAnswer(psTransport);
+ }
+ if ( (psTransport->pfDiscover_Cb != NULL) &&
+ (psTransport->nDiscoveryReqOffset < psTransport->nDiscoveryListSize) )
+ {
+ result = phFriNfc_LlcpTransport_DiscoverServicesEx(psTransport);
+ }
+
+ /* Init index */
+ index = psTransport->socketIndex;
+
+ /* Check all sockets for pending operation */
+ do
+ {
+ /* Modulo-increment index */
+ index = (index + 1) % PHFRINFC_LLCP_NB_SOCKET_MAX;
+
+ pCurrentSocket = &psTransport->pSocketTable[index];
+
+ /* Dispatch to the corresponding transport layer */
+ if (pCurrentSocket->eSocket_Type == phFriNfc_LlcpTransport_eConnectionOriented)
+ {
+ result = phFriNfc_LlcpTransport_ConnectionOriented_HandlePendingOperations(pCurrentSocket);
+ }
+ else if (pCurrentSocket->eSocket_Type == phFriNfc_LlcpTransport_eConnectionLess)
+ {
+ result = phFriNfc_LlcpTransport_Connectionless_HandlePendingOperations(pCurrentSocket);
+ }
+
+ if (result != NFCSTATUS_FAILED)
+ {
+ /* Stop looping if pending operation has been found */
+ break;
+ }
+
+ } while(index != psTransport->socketIndex);
+
+ /* Save the new index */
+ psTransport->socketIndex = index;
+}
+
+
/* TODO: comment function Transport reset */
NFCSTATUS phFriNfc_LlcpTransport_Reset (phFriNfc_LlcpTransport_t *pLlcpTransport,
phFriNfc_Llcp_t *pLlcp)
@@ -170,7 +663,10 @@ NFCSTATUS phFriNfc_LlcpTransport_Reset (phFriNfc_LlcpTransport_t *pLlcpTran
pLlcpTransport->bFrmrPending = FALSE;
pLlcpTransport->socketIndex = FALSE;
pLlcpTransport->LinkStatusError = 0;
+ pLlcpTransport->pfDiscover_Cb = NULL;
+ /* Initialize cached service name/sap table */
+ memset(pLlcpTransport->pCachedServiceNames, 0x00, sizeof(phFriNfc_Llcp_CachedServiceName_t)*PHFRINFC_LLCP_SDP_ADVERTISED_NB);
/* Reset all the socket info in the table */
for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++)
@@ -241,8 +737,9 @@ NFCSTATUS phFriNfc_LlcpTransport_Reset (phFriNfc_LlcpTransport_t *pLlcpTran
/* TODO: comment function Transport CloseAll */
NFCSTATUS phFriNfc_LlcpTransport_CloseAll (phFriNfc_LlcpTransport_t *pLlcpTransport)
{
- NFCSTATUS status = NFCSTATUS_SUCCESS;
- uint8_t i;
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ phFriNfc_Llcp_CachedServiceName_t * pCachedServiceName;
+ uint8_t i;
/* Check for NULL pointers */
if(pLlcpTransport == NULL)
@@ -265,7 +762,9 @@ NFCSTATUS phFriNfc_LlcpTransport_CloseAll (phFriNfc_LlcpTransport_t *pLlcpTransp
case phFriNfc_LlcpTransportSocket_eSocketRejected:
phFriNfc_LlcpTransport_Close(&pLlcpTransport->pSocketTable[i]);
break;
- default: break;
+ default:
+ /* Do nothing */
+ break;
}
}
else
@@ -273,6 +772,197 @@ NFCSTATUS phFriNfc_LlcpTransport_CloseAll (phFriNfc_LlcpTransport_t *pLlcpTransp
phFriNfc_LlcpTransport_Close(&pLlcpTransport->pSocketTable[i]);
}
}
+
+ /* Reset cached service name/sap table */
+ for(i=0;i<PHFRINFC_LLCP_SDP_ADVERTISED_NB;i++)
+ {
+ pCachedServiceName = &pLlcpTransport->pCachedServiceNames[i];
+
+ pCachedServiceName->nSap = 0;
+ if (pCachedServiceName->sServiceName.buffer != NULL)
+ {
+ phOsalNfc_FreeMemory(pCachedServiceName->sServiceName.buffer);
+ pCachedServiceName->sServiceName.buffer = NULL;
+ }
+ pCachedServiceName->sServiceName.length = 0;
+ }
+
+ return status;
+}
+
+
+/* TODO: comment function Transport LinkSend */
+NFCSTATUS phFriNfc_LlcpTransport_LinkSend( phFriNfc_LlcpTransport_t *LlcpTransport,
+ phFriNfc_Llcp_sPacketHeader_t *psHeader,
+ phFriNfc_Llcp_sPacketSequence_t *psSequence,
+ phNfc_sData_t *psInfo,
+ phFriNfc_Llcp_Send_CB_t pfSend_CB,
+ void *pContext )
+{
+ NFCSTATUS status;
+ /* Check if a send is already ongoing */
+ if (LlcpTransport->pfLinkSendCb != NULL)
+ {
+ return NFCSTATUS_BUSY;
+ }
+ /* Save callback details */
+ LlcpTransport->pfLinkSendCb = pfSend_CB;
+ LlcpTransport->pLinkSendContext = pContext;
+
+ /* Call the link-level send function */
+ status = phFriNfc_Llcp_Send(LlcpTransport->pLlcp, psHeader, psSequence, psInfo, phFriNfc_LlcpTransport_Send_CB, (void*)LlcpTransport);
+ if (status != NFCSTATUS_PENDING && status != NFCSTATUS_SUCCESS) {
+ // Clear out callbacks
+ LlcpTransport->pfLinkSendCb = NULL;
+ LlcpTransport->pLinkSendContext = NULL;
+ }
+ return status;
+}
+
+
+/* TODO: comment function Transport SendFrameReject */
+NFCSTATUS phFriNfc_LlcpTransport_SendFrameReject(phFriNfc_LlcpTransport_t *psTransport,
+ uint8_t dsap,
+ uint8_t rejectedPTYPE,
+ uint8_t ssap,
+ phFriNfc_Llcp_sPacketSequence_t* sLlcpSequence,
+ uint8_t WFlag,
+ uint8_t IFlag,
+ uint8_t RFlag,
+ uint8_t SFlag,
+ uint8_t vs,
+ uint8_t vsa,
+ uint8_t vr,
+ uint8_t vra)
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ phNfc_sData_t sFrmrBuffer;
+ uint8_t flagValue;
+ uint8_t sequence = 0;
+ uint8_t index;
+ uint8_t socketFound = FALSE;
+
+ /* Search a socket waiting for a FRAME */
+ for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
+ {
+ /* Test if the socket is in connected state and if its SSAP and DSAP are valid */
+ if(psTransport->pSocketTable[index].socket_sSap == dsap
+ && psTransport->pSocketTable[index].socket_dSap == ssap)
+ {
+ /* socket found */
+ socketFound = TRUE;
+ break;
+ }
+ }
+
+ /* Test if a socket has been found */
+ if(socketFound)
+ {
+ /* Set socket state to disconnected */
+ psTransport->pSocketTable[index].eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDefault;
+
+ /* Call ErrCB due to a FRMR*/
+ psTransport->pSocketTable[index].pSocketErrCb( psTransport->pSocketTable[index].pContext,PHFRINFC_LLCP_ERR_FRAME_REJECTED);
+
+ /* Close the socket */
+ status = phFriNfc_LlcpTransport_ConnectionOriented_Close(&psTransport->pSocketTable[index]);
+
+ /* Set FRMR Header */
+ psTransport->sLlcpHeader.dsap = dsap;
+ psTransport->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_FRMR;
+ psTransport->sLlcpHeader.ssap = ssap;
+
+ /* Set FRMR Information Field */
+ flagValue = (WFlag<<7) | (IFlag<<6) | (RFlag<<5) | (SFlag<<4) | rejectedPTYPE;
+ if (sLlcpSequence != NULL)
+ {
+ sequence = (uint8_t)((sLlcpSequence->ns<<4)|(sLlcpSequence->nr));
+ }
+
+ psTransport->FrmrInfoBuffer[0] = flagValue;
+ psTransport->FrmrInfoBuffer[1] = sequence;
+ psTransport->FrmrInfoBuffer[2] = (vs<<4)|vr ;
+ psTransport->FrmrInfoBuffer[3] = (vsa<<4)|vra ;
+
+ /* Test if a send is pending */
+ if(psTransport->bSendPending)
+ {
+ psTransport->bFrmrPending = TRUE;
+ status = NFCSTATUS_PENDING;
+ }
+ else
+ {
+ sFrmrBuffer.buffer = psTransport->FrmrInfoBuffer;
+ sFrmrBuffer.length = 0x04; /* Size of FRMR Information field */
+
+ /* Send Pending */
+ psTransport->bSendPending = TRUE;
+
+ /* Send FRMR frame */
+ status = phFriNfc_Llcp_Send(psTransport->pLlcp,
+ &psTransport->sLlcpHeader,
+ NULL,
+ &sFrmrBuffer,
+ phFriNfc_LlcpTransport_Send_CB,
+ psTransport);
+ }
+ }
+ else
+ {
+ /* No active socket*/
+ /* FRMR Frame not handled*/
+ }
+ return status;
+}
+
+
+/* TODO: comment function Transport SendDisconnectMode (NOTE: used only
+ * for requests not bound to a socket, like "service not found")
+ */
+NFCSTATUS phFriNfc_LlcpTransport_SendDisconnectMode(phFriNfc_LlcpTransport_t* psTransport,
+ uint8_t dsap,
+ uint8_t ssap,
+ uint8_t dmOpCode)
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+
+ /* Test if a send is pending */
+ if(psTransport->bSendPending)
+ {
+ /* DM pending */
+ psTransport->bDmPending = TRUE;
+
+ /* Store DM Info */
+ psTransport->DmInfoBuffer[0] = dsap;
+ psTransport->DmInfoBuffer[1] = ssap;
+ psTransport->DmInfoBuffer[2] = dmOpCode;
+
+ status = NFCSTATUS_PENDING;
+ }
+ else
+ {
+ /* Set the header */
+ psTransport->sDmHeader.dsap = dsap;
+ psTransport->sDmHeader.ptype = PHFRINFC_LLCP_PTYPE_DM;
+ psTransport->sDmHeader.ssap = ssap;
+
+ /* Save Operation Code to be provided in DM frame payload */
+ psTransport->DmInfoBuffer[2] = dmOpCode;
+ psTransport->sDmPayload.buffer = &psTransport->DmInfoBuffer[2];
+ psTransport->sDmPayload.length = PHFRINFC_LLCP_DM_LENGTH;
+
+ /* Send Pending */
+ psTransport->bSendPending = TRUE;
+
+ /* Send DM frame */
+ status = phFriNfc_Llcp_Send(psTransport->pLlcp,
+ &psTransport->sDmHeader,
+ NULL,
+ &psTransport->sDmPayload,
+ phFriNfc_LlcpTransport_Send_CB,
+ psTransport);
+ }
+
return status;
}
@@ -376,6 +1066,101 @@ NFCSTATUS phFriNfc_LlcpTransport_SocketGetRemoteOptions(phFriNfc_LlcpTransport_S
return status;
}
+
+static NFCSTATUS phFriNfc_LlcpTransport_DiscoverServicesEx(phFriNfc_LlcpTransport_t *psTransport)
+{
+ NFCSTATUS result = NFCSTATUS_PENDING;
+ phNfc_sData_t sInfoBuffer;
+ phNfc_sData_t *psServiceName;
+ uint32_t nTlvOffset;
+
+ /* Test if a send is pending */
+ if(!psTransport->bSendPending)
+ {
+ /* Set the header */
+ psTransport->sLlcpHeader.dsap = PHFRINFC_LLCP_SAP_SDP;
+ psTransport->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_SNL;
+ psTransport->sLlcpHeader.ssap = PHFRINFC_LLCP_SAP_SDP;
+
+ /* Prepare the info buffer */
+ sInfoBuffer.buffer = psTransport->pDiscoveryBuffer;
+ sInfoBuffer.length = sizeof(psTransport->pDiscoveryBuffer);
+
+ /* Encode as many requests as possible */
+ nTlvOffset = 0;
+ while(psTransport->nDiscoveryReqOffset < psTransport->nDiscoveryListSize)
+ {
+ /* Get current service name and try to encode it in SNL frame */
+ psServiceName = &psTransport->psDiscoveryServiceNameList[psTransport->nDiscoveryReqOffset];
+ result = phFriNfc_LlcpTransport_EncodeSdreqTlv(&sInfoBuffer,
+ &nTlvOffset,
+ psTransport->nDiscoveryReqOffset,
+ psServiceName);
+ if (result != NFCSTATUS_SUCCESS)
+ {
+ /* Impossible to fit more requests in a single frame,
+ * will be continued on next opportunity
+ */
+ break;
+ }
+
+ /* Update request counter */
+ psTransport->nDiscoveryReqOffset++;
+ }
+
+ /* Update buffer length to match real TLV size */
+ sInfoBuffer.length = nTlvOffset;
+
+ /* Send Pending */
+ psTransport->bSendPending = TRUE;
+
+ /* Send SNL frame */
+ result = phFriNfc_Llcp_Send(psTransport->pLlcp,
+ &psTransport->sLlcpHeader,
+ NULL,
+ &sInfoBuffer,
+ phFriNfc_LlcpTransport_Send_CB,
+ psTransport);
+ }
+ else
+ {
+ /* Impossible to send now, this function will be called again on next opportunity */
+ }
+
+ return result;
+}
+
+/*!
+* \ingroup grp_fri_nfc
+* \brief <b>Discover remote services SAP using SDP protocol</b>.
+ */
+NFCSTATUS phFriNfc_LlcpTransport_DiscoverServices( phFriNfc_LlcpTransport_t *pLlcpTransport,
+ phNfc_sData_t *psServiceNameList,
+ uint8_t *pnSapList,
+ uint8_t nListSize,
+ pphFriNfc_Cr_t pDiscover_Cb,
+ void *pContext )
+{
+ NFCSTATUS result = NFCSTATUS_FAILED;
+
+ /* Save request details */
+ pLlcpTransport->psDiscoveryServiceNameList = psServiceNameList;
+ pLlcpTransport->pnDiscoverySapList = pnSapList;
+ pLlcpTransport->nDiscoveryListSize = nListSize;
+ pLlcpTransport->pfDiscover_Cb = pDiscover_Cb;
+ pLlcpTransport->pDiscoverContext = pContext;
+
+ /* Reset internal counters */
+ pLlcpTransport->nDiscoveryReqOffset = 0;
+ pLlcpTransport->nDiscoveryResOffset = 0;
+
+ /* Perform request */
+ result = phFriNfc_LlcpTransport_DiscoverServicesEx(pLlcpTransport);
+
+ return result;
+}
+
+
/**
* \ingroup grp_fri_nfc
* \brief <b>Create a socket on a LLCP-connected device</b>.
@@ -570,8 +1355,9 @@ NFCSTATUS phFriNfc_LlcpTransport_Close(phFriNfc_LlcpTransport_Socket_t* pLlcpS
*
* This function binds the socket to a local Service Access Point.
*
-* \param[out] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
-* \param[in] pConfigInfo A port number for a specific socket
+* \param[in] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
+* \param[in] nSap The SAP number to bind with, or 0 for auto-bind to a free SAP.
+* \param[in] psServiceName A pointer to Service Name, or NULL if no service name.
*
* \retval NFCSTATUS_SUCCESS Operation successful.
* \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
@@ -584,10 +1370,13 @@ NFCSTATUS phFriNfc_LlcpTransport_Close(phFriNfc_LlcpTransport_Socket_t* pLlcpS
*/
NFCSTATUS phFriNfc_LlcpTransport_Bind(phFriNfc_LlcpTransport_Socket_t *pLlcpSocket,
- uint8_t nSap)
+ uint8_t nSap,
+ phNfc_sData_t *psServiceName)
{
NFCSTATUS status = NFCSTATUS_SUCCESS;
uint8_t i;
+ uint8_t min_sap_range;
+ uint8_t max_sap_range;
/* Check for NULL pointers */
if(pLlcpSocket == NULL)
@@ -598,25 +1387,59 @@ NFCSTATUS phFriNfc_LlcpTransport_Bind(phFriNfc_LlcpTransport_Socket_t *pLlcpS
{
status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
}
- else if(nSap<2 || nSap>63)
- {
- status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
- }
else
{
- /* Test if the nSap it is useb by another socket */
- for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++)
+ /* Calculate authorized SAP range */
+ if ((psServiceName != NULL) && (psServiceName->length > 0))
+ {
+ /* SDP advertised service */
+ min_sap_range = PHFRINFC_LLCP_SAP_SDP_ADVERTISED_FIRST;
+ max_sap_range = PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST;
+ }
+ else
{
- if((pLlcpSocket->psTransport->pSocketTable[i].socket_sSap == nSap)
- && (pLlcpSocket->psTransport->pSocketTable[i].eSocket_Type == pLlcpSocket->eSocket_Type))
+ /* Non-SDP advertised service */
+ min_sap_range = PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST;
+ max_sap_range = PHFRINFC_LLCP_SAP_NUMBER;
+ }
+
+ /* Handle dynamic SAP allocation */
+ if (nSap == 0)
+ {
+ status = phFriNfc_LlcpTransport_GetFreeSap(pLlcpSocket->psTransport, psServiceName, &nSap);
+ if (status != NFCSTATUS_SUCCESS)
{
- return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_ALREADY_REGISTERED);
+ return status;
}
}
- /* Set the nSap value of the socket */
- pLlcpSocket->socket_sSap = nSap;
- /* Set the socket state */
- pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketBound;
+
+ /* Test the SAP range */
+ if(!IS_BETWEEN(nSap, min_sap_range, max_sap_range) &&
+ !IS_BETWEEN(nSap, PHFRINFC_LLCP_SAP_WKS_FIRST, PHFRINFC_LLCP_SAP_SDP_ADVERTISED_FIRST))
+ {
+ status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ /* Test if the nSap it is used by another socket */
+ for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++)
+ {
+ if(pLlcpSocket->psTransport->pSocketTable[i].socket_sSap == nSap)
+ {
+ return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_ALREADY_REGISTERED);
+ }
+ }
+ /* Set service name */
+ status = phFriNfc_LlcpTransport_RegisterName(pLlcpSocket, nSap, psServiceName);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ return status;
+ }
+ /* Set the nSap value of the socket */
+ pLlcpSocket->socket_sSap = nSap;
+ /* Set the socket state */
+ pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketBound;
+ }
}
return status;
}
@@ -637,7 +1460,6 @@ NFCSTATUS phFriNfc_LlcpTransport_Bind(phFriNfc_LlcpTransport_Socket_t *pLlcpS
*
*
* \param[in] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
-* \param[in] psServiceName A pointer to Service Name
* \param[in] pListen_Cb The callback to be called each time the
* socket receive a connection request.
* \param[in] pContext Upper layer context to be returned in
@@ -651,14 +1473,13 @@ NFCSTATUS phFriNfc_LlcpTransport_Bind(phFriNfc_LlcpTransport_Socket_t *pLlcpS
* \retval NFCSTATUS_FAILED Operation failed.
*/
NFCSTATUS phFriNfc_LlcpTransport_Listen(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket,
- phNfc_sData_t *psServiceName,
pphFriNfc_LlcpTransportSocketListenCb_t pListen_Cb,
void* pContext)
{
NFCSTATUS status = NFCSTATUS_SUCCESS;
/* Check for NULL pointers */
- if(pLlcpSocket == NULL || pListen_Cb == NULL|| pContext == NULL || psServiceName == NULL)
+ if(pLlcpSocket == NULL || pListen_Cb == NULL|| pContext == NULL )
{
status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
}
@@ -677,33 +1498,107 @@ NFCSTATUS phFriNfc_LlcpTransport_Listen(phFriNfc_LlcpTransport_Socket_t*
{
status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
}
- /* Test the length of the SN */
- else if(psServiceName->length > PHFRINFC_LLCP_SN_MAX_LENGTH)
+ else
{
- status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
+ status = phFriNfc_LlcpTransport_ConnectionOriented_Listen(pLlcpSocket,
+ pListen_Cb,
+ pContext);
}
- /* Test the SAP range for SDP-advertised services */
- else if((psServiceName->length > 0) &&
- (!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_SDP_ADVERTISED_FIRST, PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST)) &&
- (!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_WKS_FIRST, PHFRINFC_LLCP_SAP_SDP_ADVERTISED_FIRST)))
+ return status;
+}
+
+
+/**
+* \ingroup grp_fri_nfc
+* \brief <b>Register the socket service name</b>.
+*
+* This function changes the service name of the corresponding socket.
+*
+* \param[in] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
+* \param[in] nSap SAP number associated to the service name.
+* \param[in] psServiceName A pointer to a Service Name.
+*
+* \retval NFCSTATUS_SUCCESS Operation successful.
+* \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
+* could not be properly interpreted.
+* \retval NFCSTATUS_FAILED Operation failed.
+*/
+static NFCSTATUS phFriNfc_LlcpTransport_RegisterName(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket,
+ uint8_t nSap,
+ phNfc_sData_t *psServiceName)
+{
+ phFriNfc_LlcpTransport_t * psTransport = pLlcpSocket->psTransport;
+ uint8_t index;
+ uint8_t bSnMatch, bSapMatch;
+
+ /* Check in cache if sap has been used for different service name */
+ for(index=0 ; index<PHFRINFC_LLCP_SDP_ADVERTISED_NB ; index++)
{
- status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
+ if(psTransport->pCachedServiceNames[index].sServiceName.length == 0)
+ {
+ /* Reached end of table */
+ break;
+ }
+
+ bSnMatch = (memcmp(psTransport->pCachedServiceNames[index].sServiceName.buffer, psServiceName->buffer, psServiceName->length) == 0);
+ bSapMatch = psTransport->pCachedServiceNames[index].nSap == nSap;
+ if(bSnMatch && bSapMatch)
+ {
+ /* Request match cache */
+ break;
+ }
+ else if((bSnMatch && !bSapMatch) || (!bSnMatch && bSapMatch))
+ {
+ /* Request mismatch with cache */
+ return NFCSTATUS_INVALID_PARAMETER;
+ }
}
- /* Test the SAP range for non SDP-advertised services */
- else if((psServiceName->length == 0) &&
- (!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST, PHFRINFC_LLCP_SAP_NUMBER)) &&
- (!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_WKS_FIRST, PHFRINFC_LLCP_SAP_SDP_ADVERTISED_FIRST)))
+
+ /* Handle service with no name */
+ if (psServiceName == NULL)
{
- status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
+ if (pLlcpSocket->sServiceName.buffer != NULL)
+ {
+ phOsalNfc_FreeMemory(pLlcpSocket->sServiceName.buffer);
+ }
+ pLlcpSocket->sServiceName.buffer = NULL;
+ pLlcpSocket->sServiceName.length = 0;
}
else
{
- status = phFriNfc_LlcpTransport_ConnectionOriented_Listen(pLlcpSocket,
- psServiceName,
- pListen_Cb,
- pContext);
+ /* Check if name already in use */
+ for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
+ {
+ phFriNfc_LlcpTransport_Socket_t* pCurrentSocket = &pLlcpSocket->psTransport->pSocketTable[index];
+
+ if( (pCurrentSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
+ && (pCurrentSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketRegistered))
+ {
+ /* Only bound or listening sockets may have a service name */
+ continue;
+ }
+ if(pCurrentSocket->sServiceName.length != psServiceName->length) {
+ /* Service name do not match, check next */
+ continue;
+ }
+ if(memcmp(pCurrentSocket->sServiceName.buffer, psServiceName->buffer, psServiceName->length) == 0)
+ {
+ /* Service name already in use */
+ return NFCSTATUS_INVALID_PARAMETER;
+ }
+ }
+
+ /* Store the listen socket SN */
+ pLlcpSocket->sServiceName.length = psServiceName->length;
+ pLlcpSocket->sServiceName.buffer = phOsalNfc_GetMemory(psServiceName->length);
+ if (pLlcpSocket->sServiceName.buffer == NULL)
+ {
+ return NFCSTATUS_NOT_ENOUGH_MEMORY;
+ }
+ memcpy(pLlcpSocket->sServiceName.buffer, psServiceName->buffer, psServiceName->length);
}
- return status;
+
+ return NFCSTATUS_SUCCESS;
}
/**
@@ -862,6 +1757,7 @@ NFCSTATUS phFriNfc_LlcpTransport_Connect( phFriNfc_LlcpTransport_Socket_t*
void* pContext)
{
NFCSTATUS status = NFCSTATUS_SUCCESS;
+ uint8_t nLocalSap;
uint8_t i;
/* Check for NULL pointers */
@@ -879,7 +1775,11 @@ NFCSTATUS phFriNfc_LlcpTransport_Connect( phFriNfc_LlcpTransport_Socket_t*
{
status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
}
-
+ /* Test if the socket has a service name */
+ else if(pLlcpSocket->sServiceName.length != 0)
+ {
+ status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
+ }
/* Test if the socket is not in connecting or connected state*/
else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketCreated && pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
{
@@ -890,11 +1790,13 @@ NFCSTATUS phFriNfc_LlcpTransport_Connect( phFriNfc_LlcpTransport_Socket_t*
/* Implicit bind if socket is not already bound */
if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
{
- status = phFriNfc_LlcpTransport_AutoBind(pLlcpSocket);
+ /* Bind to a free sap */
+ status = phFriNfc_LlcpTransport_GetFreeSap(pLlcpSocket->psTransport, NULL, &nLocalSap);
if (status != NFCSTATUS_SUCCESS)
{
return status;
}
+ pLlcpSocket->socket_sSap = nLocalSap;
}
/* Test the SAP range for non SDP-advertised services */
@@ -947,6 +1849,7 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectByUri(phFriNfc_LlcpTransport_Socket_t*
{
NFCSTATUS status = NFCSTATUS_SUCCESS;
uint8_t i;
+ uint8_t nLocalSap;
/* Check for NULL pointers */
if(pLlcpSocket == NULL || pConnect_RspCb == NULL || pContext == NULL)
@@ -973,11 +1876,13 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectByUri(phFriNfc_LlcpTransport_Socket_t*
/* Implicit bind if socket is not already bound */
if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
{
- status = phFriNfc_LlcpTransport_AutoBind(pLlcpSocket);
+ /* Bind to a free sap */
+ status = phFriNfc_LlcpTransport_GetFreeSap(pLlcpSocket->psTransport, NULL, &nLocalSap);
if (status != NFCSTATUS_SUCCESS)
{
return status;
}
+ pLlcpSocket->socket_sSap = nLocalSap;
}
/* Test the SAP range for non SDP-advertised services */
@@ -1242,6 +2147,11 @@ NFCSTATUS phFriNfc_LlcpTransport_SendTo( phFriNfc_LlcpTransport_Socket_t
{
status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
}
+ /* Test if a send is pending */
+ else if(pLlcpSocket->pfSocketSend_Cb != NULL)
+ {
+ status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_REJECTED);
+ }
else
{
/* Get the local parameters of the LLCP Link */
diff --git a/src/phFriNfc_LlcpTransport.h b/src/phFriNfc_LlcpTransport.h
index 2aff8ea..adcab9e 100644
--- a/src/phFriNfc_LlcpTransport.h
+++ b/src/phFriNfc_LlcpTransport.h
@@ -47,6 +47,9 @@ typedef struct phFriNfc_LlcpTransport phFriNfc_LlcpTransport_t;
struct phFriNfc_LlcpTransport_Socket;
typedef struct phFriNfc_LlcpTransport_Socket phFriNfc_LlcpTransport_Socket_t;
+struct phFriNfc_Llcp_CachedServiceName;
+typedef struct phFriNfc_Llcp_CachedServiceName phFriNfc_Llcp_CachedServiceName_t;
+
/*========== ENUMERATES ===========*/
/* Enum reperesents the different LLCP Link status*/
@@ -167,6 +170,9 @@ struct phFriNfc_LlcpTransport_Socket
uint16_t localMIUX;
uint8_t index;
+ /* SDP related fields */
+ uint8_t nTid;
+
/* Information Flags */
bool_t bSocketRecvPending;
bool_t bSocketSendPending;
@@ -226,18 +232,33 @@ struct phFriNfc_LlcpTransport_Socket
/**
* \ingroup grp_fri_nfc_llcp_mac
+ * \brief TODO
+ */
+struct phFriNfc_Llcp_CachedServiceName
+{
+ phNfc_sData_t sServiceName;
+ uint8_t nSap;
+};
+
+
+/**
+ * \ingroup grp_fri_nfc_llcp_mac
* \brief Declaration of a TRANSPORT Type with a table of PHFRINFC_LLCP_NB_SOCKET_DEFAULT sockets
* and a pointer a Llcp layer
*/
struct phFriNfc_LlcpTransport
{
phFriNfc_LlcpTransport_Socket_t pSocketTable[PHFRINFC_LLCP_NB_SOCKET_MAX];
+ phFriNfc_Llcp_CachedServiceName_t pCachedServiceNames[PHFRINFC_LLCP_SDP_ADVERTISED_NB];
phFriNfc_Llcp_t *pLlcp;
bool_t bSendPending;
bool_t bRecvPending;
bool_t bDmPending;
bool_t bFrmrPending;
+ phFriNfc_Llcp_Send_CB_t pfLinkSendCb;
+ void *pLinkSendContext;
+
uint8_t socketIndex;
/**< Info field of pending FRMR packet*/
@@ -251,6 +272,22 @@ struct phFriNfc_LlcpTransport
uint8_t DmInfoBuffer[3];
uint8_t LinkStatusError;
+
+ /**< Service discovery related infos */
+ phNfc_sData_t *psDiscoveryServiceNameList;
+ uint8_t *pnDiscoverySapList;
+ uint8_t nDiscoveryListSize;
+ uint8_t nDiscoveryReqOffset;
+ uint8_t nDiscoveryResOffset;
+
+ uint8_t nDiscoveryResTidList[PHFRINFC_LLCP_SNL_RESPONSE_MAX];
+ uint8_t nDiscoveryResSapList[PHFRINFC_LLCP_SNL_RESPONSE_MAX];
+ uint8_t nDiscoveryResListSize;
+
+ uint8_t pDiscoveryBuffer[PHFRINFC_LLCP_MIU_DEFAULT];
+ pphFriNfc_Cr_t pfDiscover_Cb;
+ void *pDiscoverContext;
+
};
/*
@@ -277,6 +314,60 @@ NFCSTATUS phFriNfc_LlcpTransport_CloseAll (phFriNfc_LlcpTransport_t *pLlcpSocke
/**
+* \ingroup grp_fri_nfc
+* \brief <b>Used by transport layers to request a send on link layer</b>.
+*
+*/
+NFCSTATUS phFriNfc_LlcpTransport_LinkSend( phFriNfc_LlcpTransport_t *LlcpTransport,
+ phFriNfc_Llcp_sPacketHeader_t *psHeader,
+ phFriNfc_Llcp_sPacketSequence_t *psSequence,
+ phNfc_sData_t *psInfo,
+ phFriNfc_Llcp_Send_CB_t pfSend_CB,
+ void *pContext );
+
+
+/**
+* \ingroup grp_fri_nfc
+* \brief <b>Used by transport layers to send a DM frame</b>.
+*
+* This function is only used when the DM is not related to a DISC on a socket.
+*/
+NFCSTATUS phFriNfc_LlcpTransport_SendDisconnectMode(phFriNfc_LlcpTransport_t* psTransport,
+ uint8_t dsap,
+ uint8_t ssap,
+ uint8_t dmOpCode);
+
+/**
+* \ingroup grp_fri_nfc
+* \brief <b>Used by transport layers to send a FRMR frame</b>.
+*
+*/
+NFCSTATUS phFriNfc_LlcpTransport_SendFrameReject(phFriNfc_LlcpTransport_t *psTransport,
+ uint8_t dsap,
+ uint8_t rejectedPTYPE,
+ uint8_t ssap,
+ phFriNfc_Llcp_sPacketSequence_t* sLlcpSequence,
+ uint8_t WFlag,
+ uint8_t IFlag,
+ uint8_t RFlag,
+ uint8_t SFlag,
+ uint8_t vs,
+ uint8_t vsa,
+ uint8_t vr,
+ uint8_t vra);
+
+/*!
+* \ingroup grp_fri_nfc
+* \brief <b>Discover remote services SAP using SDP protocol</b>.
+ */
+NFCSTATUS phFriNfc_LlcpTransport_DiscoverServices( phFriNfc_LlcpTransport_t *pLlcpTransport,
+ phNfc_sData_t *psServiceNameList,
+ uint8_t *pnSapList,
+ uint8_t nListSize,
+ pphFriNfc_Cr_t pDiscover_Cb,
+ void *pContext );
+
+/**
* \ingroup grp_lib_nfc
* \brief <b>Get the local options of a socket</b>.
*
@@ -388,6 +479,7 @@ NFCSTATUS phFriNfc_LlcpTransport_Close(phFriNfc_LlcpTransport_Socket_t* pLlcpS
*
* \param[out] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
* \param[in] pConfigInfo A port number for a specific socket
+* \param TODO
*
* \retval NFCSTATUS_SUCCESS Operation successful.
* \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
@@ -399,7 +491,8 @@ NFCSTATUS phFriNfc_LlcpTransport_Close(phFriNfc_LlcpTransport_Socket_t* pLlcpS
* \retval NFCSTATUS_FAILED Operation failed.
*/
NFCSTATUS phFriNfc_LlcpTransport_Bind(phFriNfc_LlcpTransport_Socket_t *pLlcpSocket,
- uint8_t nSap);
+ uint8_t nSap,
+ phNfc_sData_t *psServiceName);
/**
* \ingroup grp_fri_nfc
@@ -413,7 +506,6 @@ NFCSTATUS phFriNfc_LlcpTransport_Bind(phFriNfc_LlcpTransport_Socket_t *pLlcpS
*
*
* \param[in] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
-* \param[in] psServiceName A pointer to a Service Name
* \param[in] pListen_Cb The callback to be called each time the
* socket receive a connection request.
* \param[in] pContext Upper layer context to be returned in
@@ -427,9 +519,9 @@ NFCSTATUS phFriNfc_LlcpTransport_Bind(phFriNfc_LlcpTransport_Socket_t *pLlcpS
* \retval NFCSTATUS_FAILED Operation failed.
*/
NFCSTATUS phFriNfc_LlcpTransport_Listen(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket,
- phNfc_sData_t *psServiceName,
pphFriNfc_LlcpTransportSocketListenCb_t pListen_Cb,
void* pContext);
+
/**
* \ingroup grp_fri_nfc
* \brief <b>Accept an incoming connection request for a socket</b>.
diff --git a/src/phFriNfc_LlcpTransport_Connection.c b/src/phFriNfc_LlcpTransport_Connection.c
index b75406b..c3b92f3 100644
--- a/src/phFriNfc_LlcpTransport_Connection.c
+++ b/src/phFriNfc_LlcpTransport_Connection.c
@@ -32,13 +32,7 @@
#include <phFriNfc_LlcpUtils.h>
/* Function definition */
-static NFCSTATUS phFriNfc_Llcp_Send_DisconnectMode_Frame(phFriNfc_LlcpTransport_t* psTransport,
- uint8_t dsap,
- uint8_t ssap,
- uint8_t dmOpCode);
-
static NFCSTATUS phFriNfc_Llcp_Send_ReceiveReady_Frame(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket);
-
static NFCSTATUS phFriNfc_Llcp_Send_ReceiveNotReady_Frame(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket);
static NFCSTATUS static_performSendInfo(phFriNfc_LlcpTransport_Socket_t * psLlcpSocket);
@@ -74,40 +68,8 @@ static void phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB(void* p
/* Get Send CB context */
psTransport = (phFriNfc_LlcpTransport_t*)pContext;
- /* Reset the FLAG send pending*/
- psTransport->bSendPending = FALSE;
-
if(status == NFCSTATUS_SUCCESS)
{
- if(psTransport->bFrmrPending)
- {
- /* Reset FRMR pending */
- psTransport->bFrmrPending = FALSE;
-
- /* Send Frmr */
- sFrmrBuffer.buffer = psTransport->FrmrInfoBuffer;
- sFrmrBuffer.length = 0x04; /* Size of FRMR Information field */
-
- result = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp,
- &psTransport->sLlcpHeader,
- NULL,
- &sFrmrBuffer,
- phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
- psTransport);
- }
- else if(psTransport->bDmPending)
- {
- /* Reset DM pending */
- psTransport->bDmPending = FALSE;
-
- /* Send DM pending */
- result = phFriNfc_Llcp_Send_DisconnectMode_Frame(psTransport,
- psTransport->DmInfoBuffer[0],
- psTransport->DmInfoBuffer[1],
- psTransport->DmInfoBuffer[2]);
- }
-
-
/* Test the socket */
switch(psTransport->pSocketTable[psTransport->socketIndex].eSocket_State)
{
@@ -142,170 +104,125 @@ static void phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB(void* p
psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb = NULL;
}
}break;
- default: break;
+ default:
+ /* Nothing to do */
+ break;
}
-
- /* Update Index value with the next socket */
- index = psTransport->socketIndex+1;
-
- /* Search for a socket with a flag Pending */
- do
+ }
+ else
+ {
+ /* Send CB error */
+ if(!psTransport->pSocketTable[psTransport->socketIndex].bSocketSendPending && psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb != NULL)
{
- if(index >= PHFRINFC_LLCP_NB_SOCKET_MAX)
- {
- index = 0;
- }
+ psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb(psTransport->pSocketTable[psTransport->socketIndex].pSendContext,status);
+ psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb = NULL;
+ }
+ }
+}
- if(psTransport->pSocketTable[index].bSocketAcceptPending == TRUE
- || psTransport->pSocketTable[index].bSocketConnectPending == TRUE
- || psTransport->pSocketTable[index].bSocketDiscPending == TRUE
- || psTransport->pSocketTable[index].bSocketRNRPending == TRUE
- || psTransport->pSocketTable[index].bSocketRRPending == TRUE
- || psTransport->pSocketTable[index].bSocketSendPending == TRUE
- || psTransport->pSocketTable[index].pfSocketSend_Cb != NULL)
- {
- /* socket found */
- socketFound = TRUE;
- psLocalLlcpSocket = &psTransport->pSocketTable[index];
- break;
- }
- else
- {
- if(index == psTransport->socketIndex)
- {
- break;
- }
- else
- {
- index ++;
- }
- }
- }while(index != ((psTransport->socketIndex+1)%PHFRINFC_LLCP_NB_SOCKET_MAX));
+NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_HandlePendingOperations(phFriNfc_LlcpTransport_Socket_t *pSocket)
+{
+ NFCSTATUS result = NFCSTATUS_FAILED;
+ phFriNfc_LlcpTransport_t *psTransport = pSocket->psTransport;
- if(socketFound == TRUE)
+ /* I FRAME */
+ if(pSocket->bSocketSendPending == TRUE)
+ {
+ /* Test the RW window */
+ if(CHECK_SEND_RW(pSocket))
{
- socketFound = FALSE;
- /* perform the command pending */
+ result = static_performSendInfo(pSocket);
+ }
+ }
+ /* RR FRAME */
+ else if(pSocket->bSocketRRPending == TRUE)
+ {
+ /* Reset RR pending */
+ pSocket->bSocketRRPending = FALSE;
- /* I FRAME */
- if(psLocalLlcpSocket->bSocketSendPending == TRUE)
- {
- /* Test the RW window */
- if(CHECK_SEND_RW(psLocalLlcpSocket))
- {
- result = static_performSendInfo(psLocalLlcpSocket);
+ /* Send RR Frame */
+ result = phFriNfc_Llcp_Send_ReceiveReady_Frame(pSocket);
+ }
+ /* RNR Frame */
+ else if(pSocket->bSocketRNRPending == TRUE)
+ {
+ /* Reset RNR pending */
+ pSocket->bSocketRNRPending = FALSE;
- /* Reset Send Pending Flag */
- psLocalLlcpSocket->bSocketSendPending = FALSE;
- }
- }
- /* RR FRAME */
- else if(psLocalLlcpSocket->bSocketRRPending == TRUE)
- {
- /* Reset RR pending */
- psLocalLlcpSocket->bSocketRRPending = FALSE;
+ /* Send RNR Frame */
+ result = phFriNfc_Llcp_Send_ReceiveNotReady_Frame(pSocket);
+ }
+ /* CC Frame */
+ else if(pSocket->bSocketAcceptPending == TRUE)
+ {
+ /* Reset Accept pending */
+ pSocket->bSocketAcceptPending = FALSE;
- /* Send RR Frame */
- result = phFriNfc_Llcp_Send_ReceiveReady_Frame(psLocalLlcpSocket);
- }
+ /* Fill the psLlcpHeader stuture with the DSAP,CC PTYPE and the SSAP */
+ pSocket->sLlcpHeader.dsap = pSocket->socket_dSap;
+ pSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_CC;
+ pSocket->sLlcpHeader.ssap = pSocket->socket_sSap;
- /* RNR Frame */
- else if(psLocalLlcpSocket->bSocketRNRPending == TRUE)
- {
- /* Reset RNR pending */
- psLocalLlcpSocket->bSocketRNRPending = FALSE;
+ /* Send Pending */
+ pSocket->psTransport->bSendPending = TRUE;
- /* Send RNR Frame */
- result = phFriNfc_Llcp_Send_ReceiveNotReady_Frame(psLocalLlcpSocket);
- }
- /* CC Frame */
- else if(psLocalLlcpSocket->bSocketAcceptPending == TRUE)
- {
- /* Reset Accept pending */
- psLocalLlcpSocket->bSocketAcceptPending = FALSE;
-
- /* Fill the psLlcpHeader stuture with the DSAP,CC PTYPE and the SSAP */
- psLocalLlcpSocket->sLlcpHeader.dsap = psLocalLlcpSocket->socket_dSap;
- psLocalLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_CC;
- psLocalLlcpSocket->sLlcpHeader.ssap = psLocalLlcpSocket->socket_sSap;
-
- /* Set the socket state to accepted */
- psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketAccepted;
-
- /* Store the index of the socket */
- psTransport->socketIndex = psLocalLlcpSocket->index;
-
- /* Send a CC Frame */
- result = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp,
- &psLocalLlcpSocket->sLlcpHeader,
- NULL,
- &psLocalLlcpSocket->sSocketSendBuffer,
- phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
- psTransport);
- }
- /* CONNECT FRAME */
- else if(psLocalLlcpSocket->bSocketConnectPending == TRUE)
- {
- /* Reset Accept pending */
- psLocalLlcpSocket->bSocketConnectPending = FALSE;
-
- /* Store the index of the socket */
- psTransport->socketIndex = psLocalLlcpSocket->index;
-
- /* Set the socket in connecting state */
- psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketConnecting;
-
- /* send CONNECT */
- result = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp,
- &psLocalLlcpSocket->sLlcpHeader,
- NULL,
- &psLocalLlcpSocket->sSocketSendBuffer,
- phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
- psTransport);
- }
- /* DISC FRAME */
- else if(psLocalLlcpSocket->bSocketDiscPending == TRUE)
- {
- /* Reset Disc Pending */
- psLocalLlcpSocket->bSocketDiscPending = FALSE;
+ /* Set the socket state to accepted */
+ pSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketAccepted;
- /* Set the socket in connecting state */
- psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDisconnecting;
+ /* Send a CC Frame */
+ result = phFriNfc_LlcpTransport_LinkSend(psTransport,
+ &pSocket->sLlcpHeader,
+ NULL,
+ &pSocket->sSocketSendBuffer,
+ phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
+ psTransport);
+ }
+ /* CONNECT FRAME */
+ else if(pSocket->bSocketConnectPending == TRUE)
+ {
+ /* Reset Accept pending */
+ pSocket->bSocketConnectPending = FALSE;
- /* Store the index of the socket */
- psTransport->socketIndex = psLocalLlcpSocket->index;
+ /* Send Pending */
+ pSocket->psTransport->bSendPending = TRUE;
- /* Send DISC */
- result = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp,
- &psLocalLlcpSocket->sLlcpHeader,
- NULL,
- &psLocalLlcpSocket->sSocketSendBuffer,
- phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
- psTransport);
+ /* Set the socket in connecting state */
+ pSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketConnecting;
- /* Call ErrCB due to a DISC */
- psLocalLlcpSocket->pSocketErrCb(psLocalLlcpSocket->pContext, PHFRINFC_LLCP_ERR_DISCONNECTED);
- }
- /* Call SEND IFRAME CB */
- else if((psLocalLlcpSocket->pfSocketSend_Cb != NULL) && !psLocalLlcpSocket->bSocketSendPending)
- {
- psLocalLlcpSocket->pfSocketSend_Cb(psLocalLlcpSocket->pSendContext,status);
- psLocalLlcpSocket->pfSocketSend_Cb = NULL;
- }
- }
- /* Reset the current length of the send buffer */
- //psTransport->pSocketTable[psTransport->socketIndex].sSocketSendBuffer.length = psTransport->pSocketTable[psTransport->socketIndex].bufferSendMaxLength;
+ /* send CONNECT */
+ result = phFriNfc_LlcpTransport_LinkSend(psTransport,
+ &pSocket->sLlcpHeader,
+ NULL,
+ &pSocket->sSocketSendBuffer,
+ phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
+ psTransport);
}
- else
+ /* DISC FRAME */
+ else if(pSocket->bSocketDiscPending == TRUE)
{
- /* Send CB error */
- if(!psTransport->pSocketTable[psTransport->socketIndex].bSocketSendPending && psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb != NULL)
- {
- psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb(psTransport->pSocketTable[psTransport->socketIndex].pSendContext,status);
- psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb = NULL;
- }
+ /* Reset Disc Pending */
+ pSocket->bSocketDiscPending = FALSE;
+
+ /* Send Pending */
+ pSocket->psTransport->bSendPending = TRUE;
+
+ /* Set the socket in connecting state */
+ pSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDisconnecting;
+
+ /* Send DISC */
+ result = phFriNfc_LlcpTransport_LinkSend(psTransport,
+ &pSocket->sLlcpHeader,
+ NULL,
+ &pSocket->sSocketSendBuffer,
+ phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
+ psTransport);
+
+ /* Call ErrCB due to a DISC */
+ pSocket->pSocketErrCb(pSocket->pContext, PHFRINFC_LLCP_ERR_DISCONNECTED);
}
+
+ return result;
}
static NFCSTATUS static_performSendInfo(phFriNfc_LlcpTransport_Socket_t * psLlcpSocket)
@@ -313,8 +230,8 @@ static NFCSTATUS static_performSendInfo(phFriNfc_LlcpTransport_Socket_t * psLlcp
phFriNfc_LlcpTransport_t *psTransport = psLlcpSocket->psTransport;
NFCSTATUS status;
- /* Reset Send Pending */
- psLlcpSocket->bSocketSendPending = FALSE;
+ /* Set transport send pending */
+ psTransport->bSendPending = TRUE;
/* Set the Header */
psLlcpSocket->sLlcpHeader.dsap = psLlcpSocket->socket_dSap;
@@ -332,16 +249,19 @@ static NFCSTATUS static_performSendInfo(phFriNfc_LlcpTransport_Socket_t * psLlcp
psTransport->socketIndex = psLlcpSocket->index;
/* Send I_PDU */
- status = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp,
+ status = phFriNfc_LlcpTransport_LinkSend(psTransport,
&psLlcpSocket->sLlcpHeader,
&psLlcpSocket->sSequence,
&psLlcpSocket->sSocketSendBuffer,
phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
- psTransport);
+ psLlcpSocket->psTransport);
/* Update VS */
psLlcpSocket->socket_VS = (psLlcpSocket->socket_VS+1)%16;
+ /* Reset Send Pending */
+ psLlcpSocket->bSocketSendPending = FALSE;
+
return status;
}
@@ -383,49 +303,6 @@ static void phFriNfc_LlcpTransport_ConnectionOriented_Abort(phFriNfc_LlcpTranspo
pLlcpSocket->pListenContext = NULL;
}
-static NFCSTATUS phFriNfc_Llcp_Send_DisconnectMode_Frame(phFriNfc_LlcpTransport_t* psTransport,
- uint8_t dsap,
- uint8_t ssap,
- uint8_t dmOpCode)
-{
- NFCSTATUS status = NFCSTATUS_SUCCESS;
-
- /* Test if a send is pending */
- if(psTransport->bSendPending)
- {
- /* DM pending */
- psTransport->bDmPending = TRUE;
-
- /* Store DM Info */
- psTransport->DmInfoBuffer[0] = dsap;
- psTransport->DmInfoBuffer[1] = ssap;
- psTransport->DmInfoBuffer[2] = dmOpCode;
-
- status = NFCSTATUS_PENDING;
- }
- else
- {
- /* Set the header */
- psTransport->sDmHeader.dsap = dsap;
- psTransport->sDmHeader.ptype = PHFRINFC_LLCP_PTYPE_DM;
- psTransport->sDmHeader.ssap = ssap;
-
- /* Save Operation Code to be provided in DM frame payload */
- psTransport->DmInfoBuffer[2] = dmOpCode;
- psTransport->sDmPayload.buffer = &psTransport->DmInfoBuffer[2];
- psTransport->sDmPayload.length = PHFRINFC_LLCP_DM_LENGTH;
-
- /* Send DM frame */
- status = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp,
- &psTransport->sDmHeader,
- NULL,
- &psTransport->sDmPayload,
- phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
- psTransport);
- }
-
- return status;
-}
static NFCSTATUS phFriNfc_Llcp_Send_ReceiveReady_Frame(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket)
{
@@ -439,6 +316,9 @@ static NFCSTATUS phFriNfc_Llcp_Send_ReceiveReady_Frame(phFriNfc_LlcpTransport_So
}
else
{
+ /* Set transport to pending */
+ pLlcpSocket->psTransport->bSendPending = TRUE;
+
/* Set the header of the RR frame */
pLlcpSocket->sLlcpHeader.dsap = pLlcpSocket->socket_dSap;
pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_RR;
@@ -455,7 +335,7 @@ static NFCSTATUS phFriNfc_Llcp_Send_ReceiveReady_Frame(phFriNfc_LlcpTransport_So
pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;
/* Send RR frame */
- status = phFriNfc_LlcpConnTransport_Send(pLlcpSocket->psTransport->pLlcp,
+ status = phFriNfc_LlcpTransport_LinkSend(pLlcpSocket->psTransport,
&pLlcpSocket->sLlcpHeader,
&pLlcpSocket->sSequence,
NULL,
@@ -479,6 +359,9 @@ static NFCSTATUS phFriNfc_Llcp_Send_ReceiveNotReady_Frame(phFriNfc_LlcpTransport
}
else
{
+ /* Set transport to pending */
+ pLlcpSocket->psTransport->bSendPending = TRUE;
+
/* Set the header of the RNR frame */
pLlcpSocket->sLlcpHeader.dsap = pLlcpSocket->socket_dSap;
pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_RNR;
@@ -495,7 +378,7 @@ static NFCSTATUS phFriNfc_Llcp_Send_ReceiveNotReady_Frame(phFriNfc_LlcpTransport
pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;
/* Send RNR frame */
- status = phFriNfc_LlcpConnTransport_Send(pLlcpSocket->psTransport->pLlcp,
+ status = phFriNfc_LlcpTransport_LinkSend(pLlcpSocket->psTransport,
&pLlcpSocket->sLlcpHeader,
&pLlcpSocket->sSequence,
NULL,
@@ -505,97 +388,6 @@ static NFCSTATUS phFriNfc_Llcp_Send_ReceiveNotReady_Frame(phFriNfc_LlcpTransport
return status;
}
-static NFCSTATUS phFriNfc_Llcp_Send_FrameReject_Frame(phFriNfc_LlcpTransport_t *psTransport,
- uint8_t dsap,
- uint8_t rejectedPTYPE,
- uint8_t ssap,
- phFriNfc_Llcp_sPacketSequence_t* sLlcpSequence,
- uint8_t WFlag,
- uint8_t IFlag,
- uint8_t RFlag,
- uint8_t SFlag,
- uint8_t vs,
- uint8_t vsa,
- uint8_t vr,
- uint8_t vra)
-{
- NFCSTATUS status = NFCSTATUS_SUCCESS;
- phNfc_sData_t sFrmrBuffer;
- uint8_t flagValue;
- uint8_t sequence = 0;
- uint8_t index;
- uint8_t socketFound = FALSE;
-
- /* Search a socket waiting for a FRAME */
- for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
- {
- /* Test if the socket is in connected state and if its SSAP and DSAP are valid */
- if(psTransport->pSocketTable[index].socket_sSap == dsap
- && psTransport->pSocketTable[index].socket_dSap == ssap)
- {
- /* socket found */
- socketFound = TRUE;
- break;
- }
- }
-
- /* Test if a socket has been found */
- if(socketFound)
- {
- /* Set socket state to disconnected */
- psTransport->pSocketTable[index].eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDefault;
-
- /* Call ErrCB due to a FRMR*/
- psTransport->pSocketTable[index].pSocketErrCb( psTransport->pSocketTable[index].pContext,PHFRINFC_LLCP_ERR_FRAME_REJECTED);
-
- /* Close the socket */
- status = phFriNfc_LlcpTransport_ConnectionOriented_Close(&psTransport->pSocketTable[index]);
-
- /* Set FRMR Header */
- psTransport->sLlcpHeader.dsap = dsap;
- psTransport->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_FRMR;
- psTransport->sLlcpHeader.ssap = ssap;
-
- /* Set FRMR Information Field */
- flagValue = (WFlag<<7) | (IFlag<<6) | (RFlag<<5) | (SFlag<<4) | rejectedPTYPE;
- if (sLlcpSequence != NULL)
- {
- sequence = (uint8_t)((sLlcpSequence->ns<<4)|(sLlcpSequence->nr));
- }
-
- psTransport->FrmrInfoBuffer[0] = flagValue;
- psTransport->FrmrInfoBuffer[1] = sequence;
- psTransport->FrmrInfoBuffer[2] = (vs<<4)|vr ;
- psTransport->FrmrInfoBuffer[3] = (vsa<<4)|vra ;
-
- /* Test if a send is pending */
- if(psTransport->bSendPending)
- {
- psTransport->bFrmrPending = TRUE;
- status = NFCSTATUS_PENDING;
- }
- else
- {
- sFrmrBuffer.buffer = psTransport->FrmrInfoBuffer;
- sFrmrBuffer.length = 0x04; /* Size of FRMR Information field */
-
- /* Send FRMR frame */
- status = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp,
- &psTransport->sLlcpHeader,
- NULL,
- &sFrmrBuffer,
- phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
- psTransport);
- }
- }
- else
- {
- /* No active socket*/
- /* FRMR Frame not handled*/
- }
- return status;
-}
-
static NFCSTATUS phFriNfc_Llcp_GetSocket_Params(phNfc_sData_t *psParamsTLV,
phNfc_sData_t *psServiceName,
uint8_t *pRemoteRW_Size,
@@ -698,19 +490,19 @@ static void Handle_ConnectionFrame(phFriNfc_LlcpTransport_t *psTransport,
{
/* Incorrect TLV */
/* send FRMR */
- status = phFriNfc_Llcp_Send_FrameReject_Frame(psTransport,
- ssap,
- PHFRINFC_LLCP_PTYPE_CONNECT,
- dsap,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00);
+ status = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
+ ssap,
+ PHFRINFC_LLCP_PTYPE_CONNECT,
+ dsap,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00);
}
else
{
@@ -829,20 +621,20 @@ static void Handle_ConnectionFrame(phFriNfc_LlcpTransport_t *psTransport,
{
/* No more socket are available */
/* Send a DM (0x21) */
- status = phFriNfc_Llcp_Send_DisconnectMode_Frame (psTransport,
- ssap,
- dsap,
- PHFRINFC_LLCP_DM_OPCODE_SOCKET_NOT_AVAILABLE);
+ status = phFriNfc_LlcpTransport_SendDisconnectMode (psTransport,
+ ssap,
+ dsap,
+ PHFRINFC_LLCP_DM_OPCODE_SOCKET_NOT_AVAILABLE);
}
}
else
{
/* Service Name not found or Port number not found */
/* Send a DM (0x02) */
- status = phFriNfc_Llcp_Send_DisconnectMode_Frame (psTransport,
- ssap,
- dsap,
- PHFRINFC_LLCP_DM_OPCODE_SAP_NOT_FOUND);
+ status = phFriNfc_LlcpTransport_SendDisconnectMode (psTransport,
+ ssap,
+ dsap,
+ PHFRINFC_LLCP_DM_OPCODE_SAP_NOT_FOUND);
}
}
@@ -868,19 +660,19 @@ static void Handle_ConnectionCompleteFrame(phFriNfc_LlcpTransport_t *psTran
{
/* Incorrect TLV */
/* send FRMR */
- status = phFriNfc_Llcp_Send_FrameReject_Frame(psTransport,
- ssap,
- PHFRINFC_LLCP_PTYPE_CC,
- dsap,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00);
+ status = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
+ ssap,
+ PHFRINFC_LLCP_PTYPE_CC,
+ dsap,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00);
}
else
{
@@ -991,37 +783,18 @@ static void Handle_DisconnectFrame(phFriNfc_LlcpTransport_t *psTransport,
psLocalLlcpSocket->bSocketSendPending = FALSE;
}
- /* Test if a send is pending with this scoket */
- if(psTransport->bSendPending)
- {
- /* Set DM pending */
- psTransport->bDmPending = TRUE;
-
- /* Set the socket disconnecting */
- psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDisconnecting;
-
- /* Send pending, store the DISC request */
- psTransport->DmInfoBuffer[0] = ssap;
- psTransport->DmInfoBuffer[1] = dsap;
- psTransport->DmInfoBuffer[2] = PHFRINFC_LLCP_DM_OPCODE_DISCONNECTED;
- }
- else
- {
- /* Set the socket disconnected */
- psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketCreated;
+ /* Update the socket state */
+ psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDisconnecting;
- /* Store the index of the socket */
- psTransport->socketIndex = psLocalLlcpSocket->index;
+ /* Send a DM*/
+ /* TODO: use a socket internal flag to save */
+ status = phFriNfc_LlcpTransport_SendDisconnectMode(psTransport,
+ ssap,
+ dsap,
+ PHFRINFC_LLCP_DM_OPCODE_DISCONNECTED);
- /* Send a DM*/
- status = phFriNfc_Llcp_Send_DisconnectMode_Frame(psTransport,
- ssap,
- dsap,
- PHFRINFC_LLCP_DM_OPCODE_DISCONNECTED);
-
- /* Call ErrCB due to a DISC */
- psTransport->pSocketTable[index].pSocketErrCb(psTransport->pSocketTable[index].pContext, PHFRINFC_LLCP_ERR_DISCONNECTED);
- }
+ /* Call ErrCB due to a DISC */
+ psTransport->pSocketTable[index].pSocketErrCb(psTransport->pSocketTable[index].pContext, PHFRINFC_LLCP_ERR_DISCONNECTED);
}
else
{
@@ -1046,19 +819,19 @@ static void Handle_DisconnetModeFrame(phFriNfc_LlcpTransport_t *psTransport
if(psData->length != PHFRINFC_LLCP_DM_LENGTH)
{
/* send FRMR */
- status = phFriNfc_Llcp_Send_FrameReject_Frame(psTransport,
- ssap,
- PHFRINFC_LLCP_PTYPE_DM,
- dsap,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00);
+ status = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
+ ssap,
+ PHFRINFC_LLCP_PTYPE_DM,
+ dsap,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00);
}
else
{
@@ -1132,7 +905,7 @@ static void Handle_Receive_IFrame(phFriNfc_LlcpTransport_t *psTransport,
phFriNfc_LlcpTransport_Socket_t* psLocalLlcpSocket = NULL;
phFriNfc_Llcp_sPacketSequence_t sLlcpLocalSequence;
- uint32_t dataLengthAvailable = 0;
+ uint32_t dataLengthAvailable = 0;
uint32_t dataLengthWrite = 0;
uint8_t index;
uint8_t socketFound = FALSE;
@@ -1226,23 +999,26 @@ static void Handle_Receive_IFrame(phFriNfc_LlcpTransport_t *psTransport,
if( WFlag != 0 || IFlag != 0 || RFlag != 0 || SFlag != 0)
{
/* Send FRMR */
- status = phFriNfc_Llcp_Send_FrameReject_Frame(psTransport,
- ssap,
- PHFRINFC_LLCP_PTYPE_I,
- dsap,
- &sLlcpLocalSequence,
- WFlag,
- IFlag,
- RFlag,
- SFlag,
- psLocalLlcpSocket->socket_VS,
- psLocalLlcpSocket->socket_VSA,
- psLocalLlcpSocket->socket_VR,
- psLocalLlcpSocket->socket_VRA);
+ status = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
+ ssap,
+ PHFRINFC_LLCP_PTYPE_I,
+ dsap,
+ &sLlcpLocalSequence,
+ WFlag,
+ IFlag,
+ RFlag,
+ SFlag,
+ psLocalLlcpSocket->socket_VS,
+ psLocalLlcpSocket->socket_VSA,
+ psLocalLlcpSocket->socket_VR,
+ psLocalLlcpSocket->socket_VRA);
}
else
{
+ /* Update VSA */
+ psLocalLlcpSocket->socket_VSA = (uint8_t)sLlcpLocalSequence.nr;
+
/* Test if the Linear Buffer length is null */
if(psLocalLlcpSocket->bufferLinearLength == 0)
{
@@ -1259,9 +1035,6 @@ static void Handle_Receive_IFrame(phFriNfc_LlcpTransport_t *psTransport,
/* Update VR */
psLocalLlcpSocket->socket_VR = (psLocalLlcpSocket->socket_VR+1)%16;
- /* Update VSA */
- psLocalLlcpSocket->socket_VSA = (uint8_t)sLlcpLocalSequence.nr;
-
/* Call the Receive CB */
psLocalLlcpSocket->pfSocketRecv_Cb(psLocalLlcpSocket->pRecvContext, NFCSTATUS_SUCCESS);
psLocalLlcpSocket->pfSocketRecv_Cb = NULL;
@@ -1327,9 +1100,6 @@ static void Handle_Receive_IFrame(phFriNfc_LlcpTransport_t *psTransport,
/* Update VR */
psLocalLlcpSocket->socket_VR = (psLocalLlcpSocket->socket_VR+1)%16;
- /* Update VSA */
- psLocalLlcpSocket->socket_VSA = (uint8_t)sLlcpLocalSequence.nr;
-
/* Update the length */
psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length = 0x00;
@@ -1456,14 +1226,14 @@ static void Handle_ReceiveReady_Frame(phFriNfc_LlcpTransport_t *psTransport
if (WFlag || IFlag || RFlag || SFlag)
{
/* Send FRMR */
- status = phFriNfc_Llcp_Send_FrameReject_Frame(psTransport,
- ssap, PHFRINFC_LLCP_PTYPE_RR, dsap,
- &sLlcpLocalSequence,
- WFlag, IFlag, RFlag, SFlag,
- psLocalLlcpSocket->socket_VS,
- psLocalLlcpSocket->socket_VSA,
- psLocalLlcpSocket->socket_VR,
- psLocalLlcpSocket->socket_VRA);
+ status = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
+ ssap, PHFRINFC_LLCP_PTYPE_RR, dsap,
+ &sLlcpLocalSequence,
+ WFlag, IFlag, RFlag, SFlag,
+ psLocalLlcpSocket->socket_VS,
+ psLocalLlcpSocket->socket_VSA,
+ psLocalLlcpSocket->socket_VR,
+ psLocalLlcpSocket->socket_VRA);
}
else
{
@@ -1571,14 +1341,14 @@ static void Handle_ReceiveNotReady_Frame(phFriNfc_LlcpTransport_t *psTransp
if( bWFlag != 0 || bIFlag != 0 || bRFlag != 0 || bSFlag != 0)
{
/* Send FRMR */
- status = phFriNfc_Llcp_Send_FrameReject_Frame(psTransport,
- ssap, PHFRINFC_LLCP_PTYPE_RNR, dsap,
- &sLlcpLocalSequence,
- bWFlag, bIFlag, bRFlag, bSFlag,
- psLocalLlcpSocket->socket_VS,
- psLocalLlcpSocket->socket_VSA,
- psLocalLlcpSocket->socket_VR,
- psLocalLlcpSocket->socket_VRA);
+ status = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
+ ssap, PHFRINFC_LLCP_PTYPE_RNR, dsap,
+ &sLlcpLocalSequence,
+ bWFlag, bIFlag, bRFlag, bSFlag,
+ psLocalLlcpSocket->socket_VS,
+ psLocalLlcpSocket->socket_VSA,
+ psLocalLlcpSocket->socket_VR,
+ psLocalLlcpSocket->socket_VRA);
}
else
{
@@ -1723,13 +1493,12 @@ void Handle_ConnectionOriented_IncommingFrame(phFriNfc_LlcpTransport_t
case PHFRINFC_LLCP_PTYPE_RESERVED1:
case PHFRINFC_LLCP_PTYPE_RESERVED2:
case PHFRINFC_LLCP_PTYPE_RESERVED3:
- case PHFRINFC_LLCP_PTYPE_RESERVED4:
{
- phFriNfc_Llcp_Send_FrameReject_Frame( psTransport,
- dsap, ptype, ssap,
- &sSequence,
- TRUE, FALSE, FALSE, FALSE,
- 0, 0, 0, 0);
+ phFriNfc_LlcpTransport_SendFrameReject( psTransport,
+ dsap, ptype, ssap,
+ &sSequence,
+ TRUE, FALSE, FALSE, FALSE,
+ 0, 0, 0, 0);
}break;
}
}
@@ -1815,7 +1584,6 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_SocketGetRemoteOptions(phFri
*
*
* \param[in] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
-* \param[in] psServiceName A pointer to a Service Name
* \param[in] pListen_Cb The callback to be called each time the
* socket receive a connection request.
* \param[in] pContext Upper layer context to be returned in
@@ -1829,37 +1597,11 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_SocketGetRemoteOptions(phFri
* \retval NFCSTATUS_FAILED Operation failed.
*/
NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Listen(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket,
- phNfc_sData_t *psServiceName,
pphFriNfc_LlcpTransportSocketListenCb_t pListen_Cb,
void* pContext)
{
NFCSTATUS status = NFCSTATUS_SUCCESS;
uint8_t index;
-
- /* Check if the service name is already registered */
- if (psServiceName != NULL)
- {
- for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
- {
- phFriNfc_LlcpTransport_Socket_t* pCurrentSocket = &pLlcpSocket->psTransport->pSocketTable[index];
-
- if((pCurrentSocket->sServiceName.length == 0) ||
- (pCurrentSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketRegistered))
- {
- /* Do not check inactive or non-SDP registered sockets */
- continue;
- }
- if(pCurrentSocket->sServiceName.length != psServiceName->length) {
- /* Service name do not match, check next */
- continue;
- }
- if(memcmp(pCurrentSocket->sServiceName.buffer, psServiceName->buffer, psServiceName->length) == 0)
- {
- /* Service name already in use */
- return NFCSTATUS_INVALID_PARAMETER;
- }
- }
- }
/* Store the listen callback */
pLlcpSocket->pfSocketListen_Cb = pListen_Cb;
@@ -1870,15 +1612,6 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Listen(phFriNfc_LlcpTranspor
/* Set RecvPending to TRUE */
pLlcpSocket->bSocketListenPending = TRUE;
- /* Store the listen socket SN */
- pLlcpSocket->sServiceName.length = psServiceName->length;
- pLlcpSocket->sServiceName.buffer = phOsalNfc_GetMemory(psServiceName->length);
- if (pLlcpSocket->sServiceName.buffer == NULL)
- {
- return NFCSTATUS_NOT_ENOUGH_MEMORY;
- }
- memcpy(pLlcpSocket->sServiceName.buffer, psServiceName->buffer, psServiceName->length);
-
/* Set the socket state*/
pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketRegistered;
@@ -2034,7 +1767,7 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Accept(phFriNfc_LlcpTranspor
pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;
/* Send a CC Frame */
- status = phFriNfc_LlcpConnTransport_Send(pLlcpSocket->psTransport->pLlcp,
+ status = phFriNfc_LlcpTransport_LinkSend(pLlcpSocket->psTransport,
&pLlcpSocket->sLlcpHeader,
NULL,
&pLlcpSocket->sSocketSendBuffer,
@@ -2085,10 +1818,10 @@ NFCSTATUS phLibNfc_LlcpTransport_ConnectionOriented_Reject( phFriNfc_LlcpTranspo
pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;
/* Send a DM*/
- status = phFriNfc_Llcp_Send_DisconnectMode_Frame(pLlcpSocket->psTransport,
- pLlcpSocket->socket_dSap,
- pLlcpSocket->socket_sSap,
- PHFRINFC_LLCP_DM_OPCODE_CONNECT_REJECTED);
+ status = phFriNfc_LlcpTransport_SendDisconnectMode(pLlcpSocket->psTransport,
+ pLlcpSocket->socket_dSap,
+ pLlcpSocket->socket_sSap,
+ PHFRINFC_LLCP_DM_OPCODE_CONNECT_REJECTED);
return status;
}
@@ -2224,7 +1957,8 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Connect( phFriNfc_LlcpTransp
/* Store the index of the socket */
pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;
- status = phFriNfc_LlcpConnTransport_Send(pLlcpSocket->psTransport->pLlcp,
+
+ status = phFriNfc_LlcpTransport_LinkSend(pLlcpSocket->psTransport,
&pLlcpSocket->sLlcpHeader,
NULL,
&pLlcpSocket->sSocketSendBuffer,
@@ -2328,7 +2062,7 @@ NFCSTATUS phLibNfc_LlcpTransport_ConnectionOriented_Disconnect(phFriNfc_LlcpTran
/* Store the index of the socket */
pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;
- status = phFriNfc_LlcpConnTransport_Send(pLlcpSocket->psTransport->pLlcp,
+ status = phFriNfc_LlcpTransport_LinkSend(pLlcpSocket->psTransport,
&pLlcpSocket->sLlcpHeader,
NULL,
NULL,
@@ -2369,6 +2103,9 @@ static void phFriNfc_LlcpTransport_ConnectionOriented_DisconnectClose_CB(void*
pLlcpSocket->socket_VR = 0;
pLlcpSocket->socket_VRA = 0;
+ pLlcpSocket->indexRwRead = 0;
+ pLlcpSocket->indexRwWrite = 0;
+
phFriNfc_LlcpTransport_ConnectionOriented_Abort(pLlcpSocket);
memset(&pLlcpSocket->sSocketOption, 0x00, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));
@@ -2430,6 +2167,9 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Close(phFriNfc_LlcpTransport
pLlcpSocket->socket_VR = 0;
pLlcpSocket->socket_VRA = 0;
+ pLlcpSocket->indexRwRead = 0;
+ pLlcpSocket->indexRwWrite = 0;
+
phFriNfc_LlcpTransport_ConnectionOriented_Abort(pLlcpSocket);
memset(&pLlcpSocket->sSocketOption, 0x00, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));
@@ -2513,8 +2253,12 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Send(phFriNfc_LlcpTransport_
}
else
{
- /* Perform I-Frame send */
+ /* Store the Send CB and context */
+ pLlcpSocket->pfSocketSend_Cb = pSend_RspCb;
+ pLlcpSocket->pSendContext = pContext;
+
status = static_performSendInfo(pLlcpSocket);
+
if(status != NFCSTATUS_PENDING)
{
LLCP_PRINT("Release Send callback");
diff --git a/src/phFriNfc_LlcpTransport_Connection.h b/src/phFriNfc_LlcpTransport_Connection.h
index 6b8dbc4..07ec1fb 100644
--- a/src/phFriNfc_LlcpTransport_Connection.h
+++ b/src/phFriNfc_LlcpTransport_Connection.h
@@ -30,13 +30,14 @@
#include <phFriNfc_Llcp.h>
-
void Handle_ConnectionOriented_IncommingFrame(phFriNfc_LlcpTransport_t *pLlcpTransport,
phNfc_sData_t *psData,
uint8_t dsap,
uint8_t ptype,
uint8_t ssap);
+NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_HandlePendingOperations(phFriNfc_LlcpTransport_Socket_t *pSocket);
+
/**
* \ingroup grp_lib_nfc
* \brief <b>Get the local options of a socket</b>.
@@ -111,7 +112,6 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Close(phFriNfc_LlcpTransport
*
*
* \param[in] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
-* \param[in] psServiceName A pointer to a Service Name
* \param[in] pListen_Cb The callback to be called each time the
* socket receive a connection request.
* \param[in] pContext Upper layer context to be returned in
@@ -125,7 +125,6 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Close(phFriNfc_LlcpTransport
* \retval NFCSTATUS_FAILED Operation failed.
*/
NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Listen(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket,
- phNfc_sData_t *psServiceName,
pphFriNfc_LlcpTransportSocketListenCb_t pListen_Cb,
void* pContext);
@@ -300,4 +299,4 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Recv( phFriNfc_LlcpTransport
phNfc_sData_t* psBuffer,
pphFriNfc_LlcpTransportSocketRecvCb_t pRecv_RspCb,
void* pContext);
-#endif /* PHFRINFC_LLCP_TRANSPORT_CONNECTION_H */ \ No newline at end of file
+#endif /* PHFRINFC_LLCP_TRANSPORT_CONNECTION_H */
diff --git a/src/phFriNfc_LlcpTransport_Connectionless.c b/src/phFriNfc_LlcpTransport_Connectionless.c
index 941c267..8d26d98 100644
--- a/src/phFriNfc_LlcpTransport_Connectionless.c
+++ b/src/phFriNfc_LlcpTransport_Connectionless.c
@@ -29,6 +29,39 @@
#include <phFriNfc_LlcpTransport.h>
#include <phFriNfc_Llcp.h>
+static void phFriNfc_LlcpTransport_Connectionless_SendTo_CB(void* pContext,
+ NFCSTATUS status);
+
+NFCSTATUS phFriNfc_LlcpTransport_Connectionless_HandlePendingOperations(phFriNfc_LlcpTransport_Socket_t *pSocket)
+{
+ NFCSTATUS status = NFCSTATUS_FAILED;
+
+ /* Check if something is pending and if transport layer is ready to send */
+ if ((pSocket->pfSocketSend_Cb != NULL) &&
+ (pSocket->psTransport->bSendPending == FALSE))
+ {
+ /* Fill the psLlcpHeader stuture with the DSAP,PTYPE and the SSAP */
+ pSocket->sLlcpHeader.dsap = pSocket->socket_dSap;
+ pSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_UI;
+ pSocket->sLlcpHeader.ssap = pSocket->socket_sSap;
+
+ /* Send to data to the approiate socket */
+ status = phFriNfc_LlcpTransport_LinkSend(pSocket->psTransport,
+ &pSocket->sLlcpHeader,
+ NULL,
+ &pSocket->sSocketSendBuffer,
+ phFriNfc_LlcpTransport_Connectionless_SendTo_CB,
+ pSocket);
+ }
+ else
+ {
+ /* Cannot send now, retry later */
+ }
+
+ return status;
+}
+
+
/* TODO: comment function Handle_Connectionless_IncommingFrame */
void Handle_Connectionless_IncommingFrame(phFriNfc_LlcpTransport_t *pLlcpTransport,
phNfc_sData_t *psData,
@@ -66,19 +99,17 @@ void Handle_Connectionless_IncommingFrame(phFriNfc_LlcpTransport_t *pLlcpTr
static void phFriNfc_LlcpTransport_Connectionless_SendTo_CB(void* pContext,
NFCSTATUS status)
{
- phFriNfc_LlcpTransport_Socket_t *pLlcpSocket = (phFriNfc_LlcpTransport_Socket_t*)pContext;
- pphFriNfc_LlcpTransportSocketSendCb_t pfSendCallback = pLlcpSocket->pfSocketSend_Cb;
-
- /* Reset the SendPending variable */
- pLlcpSocket->bSocketSendPending = FALSE;
-
- /* Clear out the callback */
- pLlcpSocket->pfSocketSend_Cb = NULL;
+ phFriNfc_LlcpTransport_Socket_t * pLlcpSocket = (phFriNfc_LlcpTransport_Socket_t*)pContext;
+ pphFriNfc_LlcpTransportSocketSendCb_t pfSavedCallback;
+ void * pSavedContext;
/* Call the send callback */
- pfSendCallback(pLlcpSocket->pSendContext,status);
-
-
+ pfSavedCallback = pLlcpSocket->pfSocketSend_Cb;
+ if (pfSavedCallback != NULL)
+ {
+ pLlcpSocket->pfSocketSend_Cb = NULL;
+ pfSavedCallback(pLlcpSocket->pSendContext, status);
+ }
}
static void phFriNfc_LlcpTransport_Connectionless_Abort(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket)
@@ -185,19 +216,19 @@ NFCSTATUS phFriNfc_LlcpTransport_Connectionless_SendTo(phFriNfc_LlcpTransport_So
pphFriNfc_LlcpTransportSocketSendCb_t pSend_RspCb,
void* pContext)
{
- NFCSTATUS status = NFCSTATUS_SUCCESS;
+ NFCSTATUS status = NFCSTATUS_FAILED;
/* Store send callback and context*/
pLlcpSocket->pfSocketSend_Cb = pSend_RspCb;
pLlcpSocket->pSendContext = pContext;
- /* Test if a send is pending with this socket */
- if(pLlcpSocket->bSocketSendPending == TRUE)
+ /* Test if a send is already pending at transport level */
+ if(pLlcpSocket->psTransport->bSendPending == TRUE)
{
- pphFriNfc_LlcpTransportSocketSendCb_t pfSendCallback = pLlcpSocket->pfSocketSend_Cb;
- status = NFCSTATUS_FAILED;
- pLlcpSocket->pfSocketSend_Cb = NULL;
- pfSendCallback(pLlcpSocket->pSendContext,status);
+ /* Save the request so it can be handled in phFriNfc_LlcpTransport_Connectionless_HandlePendingOperations() */
+ pLlcpSocket->sSocketSendBuffer = *psBuffer;
+ pLlcpSocket->socket_dSap = nSap;
+ status = NFCSTATUS_PENDING;
}
else
{
@@ -206,10 +237,8 @@ NFCSTATUS phFriNfc_LlcpTransport_Connectionless_SendTo(phFriNfc_LlcpTransport_So
pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_UI;
pLlcpSocket->sLlcpHeader.ssap = pLlcpSocket->socket_sSap;
- pLlcpSocket->bSocketSendPending = TRUE;
-
/* Send to data to the approiate socket */
- status = phFriNfc_Llcp_Send(pLlcpSocket->psTransport->pLlcp,
+ status = phFriNfc_LlcpTransport_LinkSend(pLlcpSocket->psTransport,
&pLlcpSocket->sLlcpHeader,
NULL,
psBuffer,
diff --git a/src/phFriNfc_LlcpTransport_Connectionless.h b/src/phFriNfc_LlcpTransport_Connectionless.h
index b502069..2fa263e 100644
--- a/src/phFriNfc_LlcpTransport_Connectionless.h
+++ b/src/phFriNfc_LlcpTransport_Connectionless.h
@@ -36,6 +36,8 @@ void Handle_Connectionless_IncommingFrame(phFriNfc_LlcpTransport_t *pLlcpTr
uint8_t dsap,
uint8_t ssap);
+NFCSTATUS phFriNfc_LlcpTransport_Connectionless_HandlePendingOperations(phFriNfc_LlcpTransport_Socket_t *pSocket);
+
/**
* \ingroup grp_fri_nfc
* \brief <b>Close a socket on a LLCP-connectionless device</b>.
@@ -115,4 +117,4 @@ NFCSTATUS phLibNfc_LlcpTransport_Connectionless_RecvFrom(phFriNfc_LlcpTransport_
pphFriNfc_LlcpTransportSocketRecvFromCb_t pRecv_Cb,
void* pContext);
-#endif /* PHFRINFC_LLCP_TRANSPORT_CONNECTIONLESS_H */ \ No newline at end of file
+#endif /* PHFRINFC_LLCP_TRANSPORT_CONNECTIONLESS_H */
diff --git a/src/phFriNfc_LlcpUtils.c b/src/phFriNfc_LlcpUtils.c
index 872fd51..750f513 100644
--- a/src/phFriNfc_LlcpUtils.c
+++ b/src/phFriNfc_LlcpUtils.c
@@ -86,6 +86,7 @@ NFCSTATUS phFriNfc_Llcp_EncodeTLV( phNfc_sData_t *psValueBuffer,
uint8_t *pValue)
{
uint32_t offset = *pOffset;
+ uint32_t finalOffset = offset + 2 + length; /* 2 stands for Type and Length fields size */
uint8_t i;
/* Check for NULL pointers */
@@ -100,8 +101,8 @@ NFCSTATUS phFriNfc_Llcp_EncodeTLV( phNfc_sData_t *psValueBuffer,
return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
}
- /* Check if enough room for Type and Length (with overflow check) */
- if ((offset+2 > psValueBuffer->length) && (offset+2 > offset))
+ /* Check if enough room for Type, Length and Value (with overflow check) */
+ if ((finalOffset > psValueBuffer->length) || (finalOffset < offset))
{
return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
}
@@ -126,6 +127,47 @@ NFCSTATUS phFriNfc_Llcp_EncodeTLV( phNfc_sData_t *psValueBuffer,
return NFCSTATUS_SUCCESS;
}
+NFCSTATUS phFriNfc_Llcp_AppendTLV( phNfc_sData_t *psValueBuffer,
+ uint32_t nTlvOffset,
+ uint32_t *pCurrentOffset,
+ uint8_t length,
+ uint8_t *pValue)
+{
+ uint32_t offset = *pCurrentOffset;
+ uint32_t finalOffset = offset + length;
+
+ /* Check for NULL pointers */
+ if ((psValueBuffer == NULL) || (pCurrentOffset == NULL) || (pValue == NULL))
+ {
+ return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
+ }
+
+ /* Check offset */
+ if (offset > psValueBuffer->length)
+ {
+ return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
+ }
+
+ /* Check if enough room for Type and Length (with overflow check) */
+ if ((finalOffset > psValueBuffer->length) || (finalOffset < offset))
+ {
+ return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
+ }
+
+ /* Update the LENGTH */
+ psValueBuffer->buffer[nTlvOffset+1] += length;
+
+ /* Set the VALUE */
+ memcpy(psValueBuffer->buffer + offset, pValue, length);
+ offset += length;
+
+ /* Save updated offset */
+ *pCurrentOffset = offset;
+
+ return NFCSTATUS_SUCCESS;
+}
+
+
/* TODO: comment function EncodeMIUX */
void phFriNfc_Llcp_EncodeMIUX(uint16_t miux,
uint8_t* pMiuxEncoded)
diff --git a/src/phFriNfc_LlcpUtils.h b/src/phFriNfc_LlcpUtils.h
index a1004a1..9dcb95a 100644
--- a/src/phFriNfc_LlcpUtils.h
+++ b/src/phFriNfc_LlcpUtils.h
@@ -70,6 +70,12 @@ NFCSTATUS phFriNfc_Llcp_EncodeTLV( phNfc_sData_t *psValueBuffer,
uint8_t length,
uint8_t *pValue);
+NFCSTATUS phFriNfc_Llcp_AppendTLV( phNfc_sData_t *psValueBuffer,
+ uint32_t nTlvOffset,
+ uint32_t *pCurrentOffset,
+ uint8_t length,
+ uint8_t *pValue);
+
void phFriNfc_Llcp_EncodeMIUX(uint16_t pMiux,
uint8_t* pMiuxEncoded);
diff --git a/src/phHal4Nfc_P2P.c b/src/phHal4Nfc_P2P.c
index 99c5978..eee22b0 100644
--- a/src/phHal4Nfc_P2P.c
+++ b/src/phHal4Nfc_P2P.c
@@ -33,6 +33,7 @@
#include <phOsalNfc_Timer.h>
#include <phHciNfc.h>
#include <phNfcConfig.h>
+
/* ------------------------------- Macros ------------------------------------*/
#ifdef _WIN32
@@ -66,6 +67,7 @@ phHal4Nfc_Send(
{
NFCSTATUS RetStatus = NFCSTATUS_PENDING;
phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
+
/*NULL checks*/
if((NULL == psHwReference)
||( NULL == pSendCallback )
@@ -123,8 +125,9 @@ phHal4Nfc_Send(
= sTransferData.buffer;
Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length
= sTransferData.length;
- /*If data size is less than MAX_SEND_LEN ,no chaining is required*/
- if(PH_HAL4NFC_MAX_SEND_LEN >= sTransferData.length)
+
+ /* If data size is less than Peer's Max frame length, then no chaining is required */
+ if(Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength >= sTransferData.length)
{
Hal4Ctxt->psTrcvCtxtInfo->
XchangeInfo.params.nfc_info.more_info = FALSE;
@@ -138,11 +141,11 @@ phHal4Nfc_Send(
Hal4Ctxt->psTrcvCtxtInfo->
XchangeInfo.params.nfc_info.more_info = TRUE;
Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length
- = PH_HAL4NFC_MAX_SEND_LEN;
+ = Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength;
Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer
= sTransferData.buffer;
Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent
- += PH_HAL4NFC_MAX_SEND_LEN;
+ += Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength;
}
PHDBG_INFO("HAL4:Calling Hci_Send_data()");
RetStatus = phHciNfc_Send_Data (
@@ -380,7 +383,7 @@ void phHal4Nfc_SendCompleteHandler(phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,void *pInfo)
/*More info remaining in send buffer.continue with sending remaining
bytes*/
if(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length
- > PH_HAL4NFC_MAX_SEND_LEN)
+ > Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength)
{
/*Set more info*/
Hal4Ctxt->psTrcvCtxtInfo->
@@ -391,11 +394,11 @@ void phHal4Nfc_SendCompleteHandler(phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,void *pInfo)
= (Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer
+ Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent);
Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length
- = PH_HAL4NFC_MAX_SEND_LEN;
+ = Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength;
Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent
- += PH_HAL4NFC_MAX_SEND_LEN;
+ += Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength;
Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length
- -= PH_HAL4NFC_MAX_SEND_LEN;
+ -= Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength;
PHDBG_INFO("Hal4:Calling Hci_senddata() from sendcompletehandler1");
SendStatus = phHciNfc_Send_Data (
Hal4Ctxt->psHciHandle,
diff --git a/src/phHal4Nfc_Reader.c b/src/phHal4Nfc_Reader.c
index 5a91e85..f27bb09 100644
--- a/src/phHal4Nfc_Reader.c
+++ b/src/phHal4Nfc_Reader.c
@@ -558,7 +558,7 @@ NFCSTATUS phHal4Nfc_Transceive(
Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
/*Register upper layer callback*/
Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = pTrcvCallback;
- if(PH_HAL4NFC_MAX_SEND_LEN
+ if(psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.MaxFrameLength
>= psTransceiveInfo->sSendData.length)
{
Hal4Ctxt->psTrcvCtxtInfo->
@@ -577,17 +577,17 @@ NFCSTATUS phHal4Nfc_Transceive(
Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer
= Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer;
Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length
- = PH_HAL4NFC_MAX_SEND_LEN;
+ = psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.MaxFrameLength;
#if 0
Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer
- += PH_HAL4NFC_MAX_SEND_LEN;
+ += psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.MaxFrameLength;
#else
Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent
- += PH_HAL4NFC_MAX_SEND_LEN;
+ += psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.MaxFrameLength;
#endif
/*Number of bytes remaining for next send*/
Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length
- -= PH_HAL4NFC_MAX_SEND_LEN;
+ -= psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.MaxFrameLength;
}
Hal4Ctxt->Hal4NextState = eHal4StateTransaction;
#ifdef TRANSACTION_TIMER
diff --git a/src/phHciNfc_NfcIPMgmt.c b/src/phHciNfc_NfcIPMgmt.c
index 06ef2a8..ed26ba3 100644
--- a/src/phHciNfc_NfcIPMgmt.c
+++ b/src/phHciNfc_NfcIPMgmt.c
@@ -1407,15 +1407,25 @@ phHciNfc_NfcIP_InfoUpdate(
(*reg_value & NFCIP_COMM_FACTOR);
p_nfcipinfo->max_frame_len = NFCIP_DATA_RATE_CALC(*reg_value);
- if (NULL != psHciContext->p_target_info)
+ if (p_nfcipinfo->max_frame_len > NFCIP_MAX_DEP_REQ_HDR_LEN)
{
- phHal_sNfcIPInfo_t *p_remtgt_info = NULL;
- /* This is given to user */
- p_remtgt_info =
- &(psHciContext->p_target_info->RemoteDevInfo.NfcIP_Info);
- p_remtgt_info->MaxFrameLength = p_nfcipinfo->max_frame_len;
- p_remtgt_info->Nfcip_Datarate = (phHalNfc_eDataRate_t)
+ p_nfcipinfo->max_frame_len -= NFCIP_MAX_DEP_REQ_HDR_LEN;
+
+ if (NULL != psHciContext->p_target_info)
+ {
+ phHal_sNfcIPInfo_t *p_remtgt_info = NULL;
+ /* This is given to user */
+ p_remtgt_info =
+ &(psHciContext->p_target_info->RemoteDevInfo.NfcIP_Info);
+ p_remtgt_info->MaxFrameLength = p_nfcipinfo->max_frame_len;
+ p_remtgt_info->Nfcip_Datarate = (phHalNfc_eDataRate_t)
p_nfcipinfo->initiator_speed;
+ }
+ }
+ else
+ {
+ status = PHNFCSTVAL(CID_NFC_HCI,
+ NFCSTATUS_INVALID_HCI_RESPONSE);
}
}
else
diff --git a/src/phHciNfc_NfcIPMgmt.h b/src/phHciNfc_NfcIPMgmt.h
index 38bbe43..00e4b7b 100644
--- a/src/phHciNfc_NfcIPMgmt.h
+++ b/src/phHciNfc_NfcIPMgmt.h
@@ -68,7 +68,7 @@
/* LENGTH definition */
#define NFCIP_ATR_MAX_LENGTH PHHAL_MAX_ATR_LENGTH
#define NFCIP_NFCID_LENGTH PHHAL_MAX_UID_LENGTH
-
+#define NFCIP_MAX_DEP_REQ_HDR_LEN 0x05
typedef enum phHciNfc_eNfcIPType{
NFCIP_INVALID = 0x00U,
diff --git a/src/phLibNfc.h b/src/phLibNfc.h
index 8621361..7a5c3f0 100644
--- a/src/phLibNfc.h
+++ b/src/phLibNfc.h
@@ -2611,6 +2611,47 @@ extern NFCSTATUS phLibNfc_Llcp_Socket( phLibNfc_Llcp_eSocketType_t eType,
/**
* \ingroup grp_lib_nfc
+* \brief <b>Get SAP of remote services using their names</b>.
+*
+* This function sends SDP queries to the remote peer to get the SAP to address for a given
+* service name. The queries are aggregated as much as possible for efficiency, but if all
+* the queries cannot fit in a single packet, they will be splitted in multiple packets.
+* The callback will be called only when all of the requested services names SAP will be
+* gathered. As mentionned in LLCP specification, a SAP of 0 means that the service name
+* as not been found.
+*
+* This feature is available only since LLCP v1.1, both devices must be at least v1.1 in
+* order to be able to use this function.
+*
+* \param[in] hRemoteDevice Peer handle obtained during device discovery process.
+* \param[in] psServiceNameList The list of the service names to discover.
+* \param[out] pnSapList The list of the corresponding SAP numbers, in the same
+* order than the service names list.
+* \param[in] nListSize The size of both service names and SAP list.
+* \param[in] pDiscover_Cb The callback to be called once LibNfc matched SAP for
+* all of the provided service names.
+* \param[in] pContext Upper layer context to be returned in the callback.
+*
+* \retval NFCSTATUS_SUCCESS Operation successful.
+* \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
+* could not be properly interpreted.
+* \retval NFCSTATUS_NOT_INITIALISED Indicates stack is not yet initialized.
+* \retval NFCSTATUS_SHUTDOWN Shutdown in progress.
+* \retval NFCSTATUS_FAILED Operation failed.
+* \retval NFCSTATUS_FEATURE_NOT_SUPPORTED Remote peer does not support this feature (e.g.: is v1.0).
+* \retval NFCSTATUS_BUSY Previous request in progress can not accept new request.
+*/
+extern NFCSTATUS phLibNfc_Llcp_DiscoverServices( phLibNfc_Handle hRemoteDevice,
+ phNfc_sData_t *psServiceNameList,
+ uint8_t *pnSapList,
+ uint8_t nListSize,
+ pphLibNfc_RspCb_t pDiscover_Cb,
+ void *pContext
+ );
+
+
+/**
+* \ingroup grp_lib_nfc
* \brief <b>Close a socket on a LLCP-connected device</b>.
*
* This function closes a LLCP socket previously created using phLibNfc_Llcp_Socket.
@@ -2686,9 +2727,8 @@ extern NFCSTATUS phLibNfc_Llcp_SocketGetRemoteOptions( phLibNfc_Handle
* This function binds the socket to a local Service Access Point.
*
* \param[in] hSocket Peer handle obtained during device discovery process.
-* \param[out] pConfigInfo Pointer on the variable to be filled with the configuration
-* parameters used during activation.
-*
+* \param TODO (nSap + sn)
+
* \retval NFCSTATUS_SUCCESS Operation successful.
* \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
* could not be properly interpreted.
@@ -2701,7 +2741,8 @@ extern NFCSTATUS phLibNfc_Llcp_SocketGetRemoteOptions( phLibNfc_Handle
* \retval NFCSTATUS_FAILED Operation failed.
*/
extern NFCSTATUS phLibNfc_Llcp_Bind( phLibNfc_Handle hSocket,
- uint8_t nSap
+ uint8_t nSap,
+ phNfc_sData_t * psServiceName
);
@@ -2718,8 +2759,6 @@ extern NFCSTATUS phLibNfc_Llcp_Bind( phLibNfc_Handle hSocket,
*
*
* \param[in] hSocket Socket handle obtained during socket creation.
-* \param[in] psServiceName A buffer containing the name of the service for SDP. No SDP
-* advertising if set to NULL.
* \param[in] pListen_Cb The callback to be called each time the
* socket receive a connection request.
* \param[in] pContext Upper layer context to be returned in
@@ -2735,7 +2774,6 @@ extern NFCSTATUS phLibNfc_Llcp_Bind( phLibNfc_Handle hSocket,
* \retval NFCSTATUS_FAILED Operation failed.
*/
extern NFCSTATUS phLibNfc_Llcp_Listen( phLibNfc_Handle hSocket,
- phNfc_sData_t *psServiceName,
pphLibNfc_LlcpSocketListenCb_t pListen_Cb,
void* pContext
);
diff --git a/src/phLibNfc_Internal.h b/src/phLibNfc_Internal.h
index 304ac22..c136032 100644
--- a/src/phLibNfc_Internal.h
+++ b/src/phLibNfc_Internal.h
@@ -134,6 +134,10 @@ typedef struct phLibNfc_Hal_CB_Info
pphLibNfc_LlcpLinkStatusCb_t pClientLlcpLinkCb;
void *pClientLlcpLinkCntx;
+ /*LLCP service discovery*/
+ pphLibNfc_RspCb_t pClientLlcpDiscoveryCb;
+ void *pClientLlcpDiscoveryCntx;
+
}phLibNfc_Hal_CB_Info_t;
typedef struct phLibNfc_NdefInfo
@@ -192,10 +196,10 @@ typedef struct phLibNfc_LlcpInfo
phFriNfc_Llcp_t sLlcpContext;
/* LLC Rx buffer */
- uint8_t pRxBuffer[1024];
+ uint8_t pRxBuffer[PHFRINFC_LLCP_PDU_HEADER_MAX + PHFRINFC_LLCP_MIU_DEFAULT + PHFRINFC_LLCP_MIUX_MAX];
/* LLC Tx buffer */
- uint8_t pTxBuffer[1024];
+ uint8_t pTxBuffer[PHFRINFC_LLCP_PDU_HEADER_MAX + PHFRINFC_LLCP_MIU_DEFAULT + PHFRINFC_LLCP_MIUX_MAX];
} phLibNfc_LlcpInfo_t;
diff --git a/src/phLibNfc_llcp.c b/src/phLibNfc_llcp.c
index ab518a2..799aae0 100644
--- a/src/phLibNfc_llcp.c
+++ b/src/phLibNfc_llcp.c
@@ -478,6 +478,73 @@ NFCSTATUS phLibNfc_Llcp_GetRemoteInfo( phLibNfc_Handle hRemot
return PHNFCSTATUS(result);
}
+NFCSTATUS phLibNfc_Llcp_DiscoverServices( phLibNfc_Handle hRemoteDevice,
+ phNfc_sData_t *psServiceNameList,
+ uint8_t *pnSapList,
+ uint8_t nListSize,
+ pphLibNfc_RspCb_t pDiscover_Cb,
+ void *pContext
+ )
+{
+ NFCSTATUS result;
+ PHNFC_UNUSED_VARIABLE(hRemoteDevice);
+
+ /* State checking */
+ result = static_CheckState();
+ if (result != NFCSTATUS_SUCCESS)
+ {
+ return result;
+ }
+
+ /* Parameters checking */
+ if ((hRemoteDevice == 0) ||
+ (psServiceNameList == NULL) ||
+ (pnSapList == NULL) ||
+ (nListSize == 0) ||
+ (pDiscover_Cb == NULL))
+ {
+ return NFCSTATUS_INVALID_PARAMETER;
+ }
+
+ /* Check device */
+ result = static_CheckDevice(hRemoteDevice);
+ if (result != NFCSTATUS_SUCCESS)
+ {
+ return result;
+ }
+
+ /* Prepare callback */
+ gpphLibContext->CBInfo.pClientLlcpDiscoveryCb = pDiscover_Cb;
+ gpphLibContext->CBInfo.pClientLlcpDiscoveryCntx = pContext;
+
+ /* Update state */
+ result = phLibNfc_UpdateNextState(gpphLibContext, eLibNfcHalStateTransaction);
+ if (result != NFCSTATUS_SUCCESS)
+ {
+ return result;
+ }
+
+ /* Call the component function */
+ result = phFriNfc_LlcpTransport_DiscoverServices( &gpphLibContext->llcp_cntx.sLlcpTransportContext,
+ psServiceNameList,
+ pnSapList,
+ nListSize,
+ pDiscover_Cb,
+ pContext
+ );
+ result = PHNFCSTATUS(result);
+ if ((result == NFCSTATUS_PENDING) || (result == NFCSTATUS_SUCCESS))
+ {
+ /* Nothing to do */
+ }
+ else if (result != NFCSTATUS_FAILED)
+ {
+ result = NFCSTATUS_TARGET_LOST;
+ }
+
+ return result;
+}
+
NFCSTATUS phLibNfc_Llcp_Socket( phLibNfc_Llcp_eSocketType_t eType,
phLibNfc_Llcp_sSocketOptions_t* psOptions,
phNfc_sData_t* psWorkingBuffer,
@@ -610,7 +677,8 @@ NFCSTATUS phLibNfc_Llcp_SocketGetRemoteOptions( phLibNfc_Handle
}
NFCSTATUS phLibNfc_Llcp_Bind( phLibNfc_Handle hSocket,
- uint8_t nSap
+ uint8_t nSap,
+ phNfc_sData_t * psServiceName
)
{
NFCSTATUS result;
@@ -632,13 +700,12 @@ NFCSTATUS phLibNfc_Llcp_Bind( phLibNfc_Handle hSocket,
}
/* Bind the socket to the designated port */
- result = phFriNfc_LlcpTransport_Bind(psSocket, nSap);
+ result = phFriNfc_LlcpTransport_Bind(psSocket, nSap, psServiceName);
return PHNFCSTATUS(result);
}
NFCSTATUS phLibNfc_Llcp_Listen( phLibNfc_Handle hSocket,
- phNfc_sData_t *psServiceName,
pphLibNfc_LlcpSocketListenCb_t pListen_Cb,
void* pContext
)
@@ -665,7 +732,6 @@ NFCSTATUS phLibNfc_Llcp_Listen( phLibNfc_Handle hSocket,
/* Start listening for incoming connections */
result = phFriNfc_LlcpTransport_Listen( psSocket,
- psServiceName,
(pphFriNfc_LlcpTransportSocketListenCb_t)pListen_Cb,
pContext );