summaryrefslogtreecommitdiff
path: root/src/phFriNfc_LlcpTransport_Connectionless.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/phFriNfc_LlcpTransport_Connectionless.c')
-rw-r--r--src/phFriNfc_LlcpTransport_Connectionless.c165
1 files changed, 131 insertions, 34 deletions
diff --git a/src/phFriNfc_LlcpTransport_Connectionless.c b/src/phFriNfc_LlcpTransport_Connectionless.c
index 5648c11..b27f6de 100644
--- a/src/phFriNfc_LlcpTransport_Connectionless.c
+++ b/src/phFriNfc_LlcpTransport_Connectionless.c
@@ -29,30 +29,95 @@
#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,
uint8_t dsap,
uint8_t ssap)
{
- uint8_t i=0;
+ phFriNfc_LlcpTransport_Socket_t * pSocket = NULL;
+ uint8_t i = 0;
+ uint8_t writeIndex;
+ /* Look through the socket table for a match */
for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++)
{
- /* Test if a socket is registered to get this packet */
- if(pLlcpTransport->pSocketTable[i].socket_sSap == dsap && pLlcpTransport->pSocketTable[i].bSocketRecvPending == TRUE)
+ if(pLlcpTransport->pSocketTable[i].socket_sSap == dsap)
{
- /* Reset the RecvPending variable */
- pLlcpTransport->pSocketTable[i].bSocketRecvPending = FALSE;
+ /* Socket found ! */
+ pSocket = &pLlcpTransport->pSocketTable[i];
+
+ /* Forward directly to application if a read is pending */
+ if (pSocket->bSocketRecvPending == TRUE)
+ {
+ /* Reset the RecvPending variable */
+ pSocket->bSocketRecvPending = FALSE;
+
+ /* Copy the received buffer into the receive buffer */
+ memcpy(pSocket->sSocketRecvBuffer->buffer, psData->buffer, psData->length);
- /* Copy the received buffer into the receive buffer */
- memcpy(pLlcpTransport->pSocketTable[i].sSocketRecvBuffer->buffer,psData->buffer,psData->length);
+ /* Update the received length */
+ *pSocket->receivedLength = psData->length;
- /* Update the received length */
- *pLlcpTransport->pSocketTable[i].receivedLength = psData->length;
+ /* call the recv callback */
+ pSocket->pfSocketRecvFrom_Cb(pSocket->pRecvContext, ssap, NFCSTATUS_SUCCESS);
+ pSocket->pfSocketRecvFrom_Cb = NULL;
+ }
+ /* If no read is pending, try to bufferize for later reading */
+ else
+ {
+ if((pSocket->indexRwWrite - pSocket->indexRwRead) < pSocket->localRW)
+ {
+ writeIndex = pSocket->indexRwWrite % pSocket->localRW;
+ /* Save SSAP */
+ pSocket->sSocketRwBufferTable[writeIndex].buffer[0] = ssap;
+ /* Save UI frame payload */
+ memcpy(pSocket->sSocketRwBufferTable[writeIndex].buffer + 1,
+ psData->buffer,
+ psData->length);
+ pSocket->sSocketRwBufferTable[writeIndex].length = psData->length;
- /* call the Recv callback */
- pLlcpTransport->pSocketTable[i].pfSocketRecvFrom_Cb(pLlcpTransport->pSocketTable[i].pRecvContext,ssap,NFCSTATUS_SUCCESS);
+ /* Update the RW write index */
+ pSocket->indexRwWrite++;
+ }
+ else
+ {
+ /* Unable to bufferize the packet, drop it */
+ }
+ }
break;
}
}
@@ -62,14 +127,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;
-
- /* Reset the SendPending variable */
- pLlcpSocket->bSocketSendPending = FALSE;
+ phFriNfc_LlcpTransport_Socket_t * pLlcpSocket = (phFriNfc_LlcpTransport_Socket_t*)pContext;
+ pphFriNfc_LlcpTransportSocketSendCb_t pfSavedCallback;
+ void * pSavedContext;
/* Call the send callback */
- pLlcpSocket->pfSocketSend_Cb(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)
@@ -176,17 +244,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)
{
- status = NFCSTATUS_FAILED;
- pLlcpSocket->pfSocketSend_Cb(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
{
@@ -195,10 +265,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,
@@ -241,7 +309,9 @@ NFCSTATUS phLibNfc_LlcpTransport_Connectionless_RecvFrom(phFriNfc_LlcpTransport_
pphFriNfc_LlcpTransportSocketRecvFromCb_t pRecv_Cb,
void *pContext)
{
- NFCSTATUS status = NFCSTATUS_PENDING;
+ NFCSTATUS status = NFCSTATUS_PENDING;
+ uint8_t readIndex;
+ uint8_t ssap;
if(pLlcpSocket->bSocketRecvPending)
{
@@ -249,16 +319,43 @@ NFCSTATUS phLibNfc_LlcpTransport_Connectionless_RecvFrom(phFriNfc_LlcpTransport_
}
else
{
- /* Store the callback and context*/
- pLlcpSocket->pfSocketRecvFrom_Cb = pRecv_Cb;
- pLlcpSocket->pRecvContext = pContext;
+ /* Check if pending packets in RW */
+ if(pLlcpSocket->indexRwRead != pLlcpSocket->indexRwWrite)
+ {
+ readIndex = pLlcpSocket->indexRwRead % pLlcpSocket->localRW;
- /* Store the pointer to the receive buffer */
- pLlcpSocket->sSocketRecvBuffer = psBuffer;
- pLlcpSocket->receivedLength = &psBuffer->length;
+ /* Extract ssap and buffer from RW buffer */
+ ssap = pLlcpSocket->sSocketRwBufferTable[readIndex].buffer[0];
+ memcpy(psBuffer->buffer,
+ pLlcpSocket->sSocketRwBufferTable[readIndex].buffer + 1,
+ pLlcpSocket->sSocketRwBufferTable[readIndex].length);
+ psBuffer->length = pLlcpSocket->sSocketRwBufferTable[readIndex].length;
- /* Set RecvPending to TRUE */
- pLlcpSocket->bSocketRecvPending = TRUE;
+ /* Reset RW buffer length */
+ pLlcpSocket->sSocketRwBufferTable[readIndex].length = 0;
+
+ /* Update Value Rw Read Index */
+ pLlcpSocket->indexRwRead++;
+
+ /* call the recv callback */
+ pRecv_Cb(pContext, ssap, NFCSTATUS_SUCCESS);
+
+ status = NFCSTATUS_SUCCESS;
+ }
+ /* Otherwise, wait for a packet to come */
+ else
+ {
+ /* Store the callback and context*/
+ pLlcpSocket->pfSocketRecvFrom_Cb = pRecv_Cb;
+ pLlcpSocket->pRecvContext = pContext;
+
+ /* Store the pointer to the receive buffer */
+ pLlcpSocket->sSocketRecvBuffer = psBuffer;
+ pLlcpSocket->receivedLength = &psBuffer->length;
+
+ /* Set RecvPending to TRUE */
+ pLlcpSocket->bSocketRecvPending = TRUE;
+ }
}
return status;
}