diff options
Diffstat (limited to 'src/phFriNfc_LlcpTransport_Connectionless.c')
-rw-r--r-- | src/phFriNfc_LlcpTransport_Connectionless.c | 165 |
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; } |