diff options
Diffstat (limited to 'src')
28 files changed, 1849 insertions, 754 deletions
diff --git a/src/phFriNfc_DesfireMap.c b/src/phFriNfc_DesfireMap.c index 6f132ea..d2f68dd 100644 --- a/src/phFriNfc_DesfireMap.c +++ b/src/phFriNfc_DesfireMap.c @@ -1671,7 +1671,7 @@ NFCSTATUS phFriNfc_Desfire_Update_SmartTagCapContainer(phFriNfc_NdefMap_t *N } /* check for the entire LENGTH Validity CCLEN + TLV L value == CCLEN*/ - if ( CapContSize != CCLen ) + if ( CapContSize < CCLen ) { ErrFlag=1; } diff --git a/src/phFriNfc_Llcp.c b/src/phFriNfc_Llcp.c index 2a4fcb4..8138cd3 100644 --- a/src/phFriNfc_Llcp.c +++ b/src/phFriNfc_Llcp.c @@ -627,7 +627,7 @@ static void phFriNfc_Llcp_HandleMACLinkDeactivated( phFriNfc_Llcp_t *Llcp ) } /* Reset state */ - Llcp->state = PHFRINFC_LLCP_STATE_CHECKED; + Llcp->state = PHFRINFC_LLCP_STATE_RESET_INIT; switch (state) { @@ -717,7 +717,8 @@ static void phFriNfc_Llcp_ResetLTO( phFriNfc_Llcp_t *Llcp ) { Llcp->state = PHFRINFC_LLCP_STATE_OPERATION_RECV; } - else + else if (Llcp->state != PHFRINFC_LLCP_STATE_DEACTIVATION && + Llcp->state != PHFRINFC_LLCP_STATE_RESET_INIT) { /* Not yet in OPERATION state, perform first reset */ if (Llcp->eRole == phFriNfc_LlcpMac_ePeerTypeInitiator) 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_LlcpMacNfcip.c b/src/phFriNfc_LlcpMacNfcip.c index 6fc7cf6..611571a 100644 --- a/src/phFriNfc_LlcpMacNfcip.c +++ b/src/phFriNfc_LlcpMacNfcip.c @@ -104,9 +104,9 @@ static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Chk(phFriNfc_LlcpMac_t { status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED); } + ChkLlcpMac_Cb(pContext,status); } - ChkLlcpMac_Cb(pContext,status); return status; } @@ -142,29 +142,27 @@ static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Deactivate (phFriNfc_LlcpMac_t *LlcpMa { /* Set the flag of LinkStatus to deactivate */ LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkDeactivated; - } - - if (LlcpMac->SendPending) - { - /* Reset Flag */ - LlcpMac->SendPending = FALSE; - phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, NFCSTATUS_FAILED); - } + if (LlcpMac->SendPending) + { + /* Reset Flag */ + LlcpMac->SendPending = FALSE; + phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, NFCSTATUS_FAILED); + } - if (LlcpMac->RecvPending) - { - /* Reset Flag */ - LlcpMac->RecvPending = FALSE; + if (LlcpMac->RecvPending) + { + /* Reset Flag */ + LlcpMac->RecvPending = FALSE; + phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, NFCSTATUS_FAILED); + } - phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, NFCSTATUS_FAILED); + LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context, + LlcpMac->LinkState, + NULL, + LlcpMac->PeerRemoteDevType); } - LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context, - LlcpMac->LinkState, - NULL, - LlcpMac->PeerRemoteDevType); - return status; } diff --git a/src/phFriNfc_LlcpTransport.c b/src/phFriNfc_LlcpTransport.c index 960a33a..870aeb4 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 = ssap; + psTransport->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_FRMR; + psTransport->sLlcpHeader.ssap = dsap; + + /* 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>. @@ -421,7 +1206,12 @@ NFCSTATUS phFriNfc_LlcpTransport_Socket(phFriNfc_LlcpTransport_t uint8_t cpt; /* Check for NULL pointers */ - if (((NULL == psOptions) && (eType != phFriNfc_LlcpTransport_eConnectionLess)) || ((psWorkingBuffer == NULL) && (eType != phFriNfc_LlcpTransport_eConnectionLess)) || pLlcpSocket == NULL || pErr_Cb == NULL || pContext == NULL || pLlcpTransport == NULL) + if ( ((psOptions == NULL) && (eType == phFriNfc_LlcpTransport_eConnectionOriented)) + || ((psWorkingBuffer == NULL) && (eType == phFriNfc_LlcpTransport_eConnectionOriented)) + || (pLlcpSocket == NULL) + || (pErr_Cb == NULL) + || (pContext == NULL) + || (pLlcpTransport == NULL)) { status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER); return status; @@ -432,12 +1222,19 @@ NFCSTATUS phFriNfc_LlcpTransport_Socket(phFriNfc_LlcpTransport_t status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER); return status; } + /* Connectionless sockets don't support options */ + else if ((psOptions != NULL) && (eType == phFriNfc_LlcpTransport_eConnectionLess)) + { + status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER); + return status; + } /* Get the local parameters of the LLCP Link */ status = phFriNfc_Llcp_GetLocalInfo(pLlcpTransport->pLlcp,&LlcpLinkParamInfo); if(status != NFCSTATUS_SUCCESS) { status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED); + return status; } else { @@ -457,56 +1254,89 @@ NFCSTATUS phFriNfc_LlcpTransport_Socket(phFriNfc_LlcpTransport_t pLlcpTransport->pSocketTable[index].pContext = pContext; /* Set the pointers to the different working buffers */ - if(pLlcpTransport->pSocketTable[index].eSocket_Type != phFriNfc_LlcpTransport_eConnectionLess) + if (eType == phFriNfc_LlcpTransport_eConnectionOriented) + { + /* Test the socket options */ + if (psOptions->rw > PHFRINFC_LLCP_RW_MAX) + { + status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER); + return status; + } + + /* Set socket options */ + memcpy(&pLlcpTransport->pSocketTable[index].sSocketOption, psOptions, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t)); + + /* Set socket local params (MIUX & RW) */ + pLlcpTransport->pSocketTable[index].localMIUX = (pLlcpTransport->pSocketTable[index].sSocketOption.miu - PHFRINFC_LLCP_MIU_DEFAULT) & PHFRINFC_LLCP_TLV_MIUX_MASK; + pLlcpTransport->pSocketTable[index].localRW = pLlcpTransport->pSocketTable[index].sSocketOption.rw & PHFRINFC_LLCP_TLV_RW_MASK; + + /* Set the Max length for the Send and Receive Window Buffer */ + pLlcpTransport->pSocketTable[index].bufferSendMaxLength = pLlcpTransport->pSocketTable[index].sSocketOption.miu; + pLlcpTransport->pSocketTable[index].bufferRwMaxLength = pLlcpTransport->pSocketTable[index].sSocketOption.miu * ((pLlcpTransport->pSocketTable[index].sSocketOption.rw & PHFRINFC_LLCP_TLV_RW_MASK)); + pLlcpTransport->pSocketTable[index].bufferLinearLength = psWorkingBuffer->length - pLlcpTransport->pSocketTable[index].bufferSendMaxLength - pLlcpTransport->pSocketTable[index].bufferRwMaxLength; + + /* Test the connection oriented buffers length */ + if((pLlcpTransport->pSocketTable[index].bufferSendMaxLength + pLlcpTransport->pSocketTable[index].bufferRwMaxLength) > psWorkingBuffer->length + || ((pLlcpTransport->pSocketTable[index].bufferLinearLength < PHFRINFC_LLCP_MIU_DEFAULT) && (pLlcpTransport->pSocketTable[index].bufferLinearLength != 0))) + { + status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_BUFFER_TOO_SMALL); + return status; + } + + /* Set the pointer and the length for the Receive Window Buffer */ + for(cpt=0;cpt<pLlcpTransport->pSocketTable[index].localRW;cpt++) + { + pLlcpTransport->pSocketTable[index].sSocketRwBufferTable[cpt].buffer = psWorkingBuffer->buffer + (cpt*pLlcpTransport->pSocketTable[index].sSocketOption.miu); + pLlcpTransport->pSocketTable[index].sSocketRwBufferTable[cpt].length = 0; + } + + /* Set the pointer and the length for the Send Buffer */ + pLlcpTransport->pSocketTable[index].sSocketSendBuffer.buffer = psWorkingBuffer->buffer + pLlcpTransport->pSocketTable[index].bufferRwMaxLength; + pLlcpTransport->pSocketTable[index].sSocketSendBuffer.length = pLlcpTransport->pSocketTable[index].bufferSendMaxLength; + + /** Set the pointer and the length for the Linear Buffer */ + pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.buffer = psWorkingBuffer->buffer + pLlcpTransport->pSocketTable[index].bufferRwMaxLength + pLlcpTransport->pSocketTable[index].bufferSendMaxLength; + pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.length = pLlcpTransport->pSocketTable[index].bufferLinearLength; + + if(pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.length != 0) + { + /* Init Cyclic Fifo */ + phFriNfc_Llcp_CyclicFifoInit(&pLlcpTransport->pSocketTable[index].sCyclicFifoBuffer, + pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.buffer, + pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.length); + } + } + /* Handle connectionless socket with buffering option */ + else if (eType == phFriNfc_LlcpTransport_eConnectionLess) { - /* Test the socket options */ - if((psOptions->rw > PHFRINFC_LLCP_RW_MAX) && (eType == phFriNfc_LlcpTransport_eConnectionOriented)) + /* Determine how many packets can be bufferized in working buffer */ + if (psWorkingBuffer != NULL) { - status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER); + /* NOTE: the extra byte is used to store SSAP */ + pLlcpTransport->pSocketTable[index].localRW = psWorkingBuffer->length / (pLlcpTransport->pLlcp->sLocalParams.miu + 1); } - /* Set socket options */ - memcpy(&pLlcpTransport->pSocketTable[index].sSocketOption, psOptions, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t)); - - /* Set socket local params (MIUX & RW) */ - pLlcpTransport->pSocketTable[index].localMIUX = (pLlcpTransport->pSocketTable[index].sSocketOption.miu - PHFRINFC_LLCP_MIU_DEFAULT) & PHFRINFC_LLCP_TLV_MIUX_MASK; - pLlcpTransport->pSocketTable[index].localRW = pLlcpTransport->pSocketTable[index].sSocketOption.rw & PHFRINFC_LLCP_TLV_RW_MASK; - - /* Set the Max length for the Send and Receive Window Buffer */ - pLlcpTransport->pSocketTable[index].bufferSendMaxLength = pLlcpTransport->pSocketTable[index].sSocketOption.miu; - pLlcpTransport->pSocketTable[index].bufferRwMaxLength = pLlcpTransport->pSocketTable[index].sSocketOption.miu * ((pLlcpTransport->pSocketTable[index].sSocketOption.rw & PHFRINFC_LLCP_TLV_RW_MASK)); - pLlcpTransport->pSocketTable[index].bufferLinearLength = psWorkingBuffer->length - pLlcpTransport->pSocketTable[index].bufferSendMaxLength - pLlcpTransport->pSocketTable[index].bufferRwMaxLength; - - /* Test the connection oriented buffers length */ - if((pLlcpTransport->pSocketTable[index].bufferSendMaxLength + pLlcpTransport->pSocketTable[index].bufferRwMaxLength) > psWorkingBuffer->length - || ((pLlcpTransport->pSocketTable[index].bufferLinearLength < PHFRINFC_LLCP_MIU_DEFAULT) && (pLlcpTransport->pSocketTable[index].bufferLinearLength != 0))) + else { - status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_BUFFER_TOO_SMALL); - return status; + pLlcpTransport->pSocketTable[index].localRW = 0; } - /* Set the pointer and the length for the Receive Window Buffer */ - for(cpt=0;cpt<pLlcpTransport->pSocketTable[index].localRW;cpt++) + if (pLlcpTransport->pSocketTable[index].localRW > PHFRINFC_LLCP_RW_MAX) { - pLlcpTransport->pSocketTable[index].sSocketRwBufferTable[cpt].buffer = psWorkingBuffer->buffer + (cpt*pLlcpTransport->pSocketTable[index].sSocketOption.miu); - pLlcpTransport->pSocketTable[index].sSocketRwBufferTable[cpt].length = 0; + pLlcpTransport->pSocketTable[index].localRW = PHFRINFC_LLCP_RW_MAX; } - /* Set the pointer and the length for the Send Buffer */ - pLlcpTransport->pSocketTable[index].sSocketSendBuffer.buffer = psWorkingBuffer->buffer + pLlcpTransport->pSocketTable[index].bufferRwMaxLength; - pLlcpTransport->pSocketTable[index].sSocketSendBuffer.length = pLlcpTransport->pSocketTable[index].bufferSendMaxLength; - - /** Set the pointer and the length for the Linear Buffer */ - pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.buffer = psWorkingBuffer->buffer + pLlcpTransport->pSocketTable[index].bufferRwMaxLength + pLlcpTransport->pSocketTable[index].bufferSendMaxLength; - pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.length = pLlcpTransport->pSocketTable[index].bufferLinearLength; - - if(pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.length != 0) + /* Set the pointers and the lengths for buffering */ + for(cpt=0 ; cpt<pLlcpTransport->pSocketTable[index].localRW ; cpt++) { - /* Init Cyclic Fifo */ - phFriNfc_Llcp_CyclicFifoInit(&pLlcpTransport->pSocketTable[index].sCyclicFifoBuffer, - pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.buffer, - pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.length); + pLlcpTransport->pSocketTable[index].sSocketRwBufferTable[cpt].buffer = psWorkingBuffer->buffer + (cpt*(pLlcpTransport->pLlcp->sLocalParams.miu + 1)); + pLlcpTransport->pSocketTable[index].sSocketRwBufferTable[cpt].length = 0; } + + /* Set other socket internals */ + pLlcpTransport->pSocketTable[index].indexRwRead = 0; + pLlcpTransport->pSocketTable[index].indexRwWrite = 0; } + /* Store index of the socket */ pLlcpTransport->pSocketTable[index].index = index; @@ -570,8 +1400,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 +1415,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 +1432,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 + { + /* 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) { - if((pLlcpSocket->psTransport->pSocketTable[i].socket_sSap == nSap) - && (pLlcpSocket->psTransport->pSocketTable[i].eSocket_Type == pLlcpSocket->eSocket_Type)) + 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 +1505,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 +1518,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 +1543,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 +1802,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 +1820,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 +1835,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 +1894,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 +1921,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 +2192,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..63e2ff5 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, + dsap, + PHFRINFC_LLCP_PTYPE_CONNECT, + ssap, + 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, + dsap, + PHFRINFC_LLCP_PTYPE_CC, + ssap, + 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, + dsap, + PHFRINFC_LLCP_PTYPE_DM, + ssap, + 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, + dsap, + PHFRINFC_LLCP_PTYPE_I, + ssap, + &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) { @@ -1250,7 +1026,7 @@ static void Handle_Receive_IFrame(phFriNfc_LlcpTransport_t *psTransport, if(psLocalLlcpSocket->bSocketRecvPending == TRUE && (psLocalLlcpSocket->indexRwWrite == psLocalLlcpSocket->indexRwRead)) { /* Reset Flag */ - psTransport->pSocketTable[psTransport->socketIndex].bSocketRecvPending = FALSE; + psLocalLlcpSocket->bSocketRecvPending = FALSE; /* Save I_FRAME into the Receive Buffer */ memcpy(psLocalLlcpSocket->sSocketRecvBuffer->buffer,psData->buffer,psData->length); @@ -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, + dsap, PHFRINFC_LLCP_PTYPE_RR, ssap, + &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, + dsap, PHFRINFC_LLCP_PTYPE_RNR, ssap, + &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 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; } 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/phFriNfc_MifareULMap.c b/src/phFriNfc_MifareULMap.c index 8d1df81..efaaceb 100644 --- a/src/phFriNfc_MifareULMap.c +++ b/src/phFriNfc_MifareULMap.c @@ -1584,7 +1584,9 @@ static NFCSTATUS phFriNfc_MfUL_H_findNDEFTLV(phFriNfc_NdefMap_t *NdefMap, if ((NdefMap->SendRecvBuf[Temp16Bytes] == PH_FRINFC_NDEFMAP_MFUL_LOCK_CTRL_TLV) || (NdefMap->SendRecvBuf[Temp16Bytes] == - PH_FRINFC_NDEFMAP_MFUL_MEM_CTRL_TLV) ) + PH_FRINFC_NDEFMAP_MFUL_MEM_CTRL_TLV) || + (NdefMap->SendRecvBuf[Temp16Bytes] == + PH_FRINFC_NDEFMAP_MFUL_PROPRIETRY_TLV)) { NdefMap->TLVStruct.NdefTLVByte = diff --git a/src/phHal4Nfc.c b/src/phHal4Nfc.c index a579811..0f6ce2b 100644 --- a/src/phHal4Nfc.c +++ b/src/phHal4Nfc.c @@ -316,20 +316,20 @@ int dlopen_firmware() { void *handle = dlopen(FW_PATH, RTLD_NOW); if (handle == NULL) { - LOGE("Could not open %s", FW_PATH); + ALOGE("Could not open %s", FW_PATH); return -1; } p = dlsym(handle, "nxp_nfc_full_version"); if (p == NULL) { - LOGE("Could not link nxp_nfc_full_version"); + ALOGE("Could not link nxp_nfc_full_version"); return -1; } nxp_nfc_full_version = (unsigned char *)p; p = dlsym(handle, "nxp_nfc_fw"); if (p == NULL) { - LOGE("Could not link nxp_nfc_fw"); + ALOGE("Could not link nxp_nfc_fw"); return -1; } nxp_nfc_fw = (unsigned char *)p; diff --git a/src/phHal4Nfc_Emulation.c b/src/phHal4Nfc_Emulation.c index b231f1e..6bb60e2 100644 --- a/src/phHal4Nfc_Emulation.c +++ b/src/phHal4Nfc_Emulation.c @@ -140,8 +140,6 @@ NFCSTATUS phHal4Nfc_Switch_SMX_Mode( } else { - /* Register Upper layer context */ - Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; /* Switch request to Wired mode */ if(eSmartMx_Wired == smx_mode) { @@ -270,8 +268,6 @@ NFCSTATUS phHal4Nfc_Switch_Swp_Mode( } else { - /* Register Upper layer context */ - Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; /*Switch mode to On or off*/ CfgStatus = phHciNfc_Switch_SwpMode( Hal4Ctxt->psHciHandle, 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_DevMgmt.c b/src/phHciNfc_DevMgmt.c index 9517741..358f8eb 100644 --- a/src/phHciNfc_DevMgmt.c +++ b/src/phHciNfc_DevMgmt.c @@ -1370,7 +1370,7 @@ phHciNfc_Recv_DevMgmt_Event( case NXP_EVT_INFO_MEM_VIOLATION: { event_info.eventType = NFC_INFO_MEM_VIOLATION; - LOGW("Your NFC controller is kinda hosed, take it to npelly@ to fix"); + ALOGW("Your NFC controller is kinda hosed, take it to npelly@ to fix"); break; } case NXP_EVT_INFO_TEMP_OVERHEAT: diff --git a/src/phHciNfc_Generic.h b/src/phHciNfc_Generic.h index 1d7b522..de4bbfd 100644 --- a/src/phHciNfc_Generic.h +++ b/src/phHciNfc_Generic.h @@ -76,7 +76,7 @@ extern char phOsalNfc_DbgTraceBuffer[]; #define MAX_TRACE_BUFFER 150 /* #define HCI_PRINT( str ) phOsalNfc_DbgTrace(str) */ #define HCI_PRINT( str ) phOsalNfc_DbgString(str) -#define HCI_DEBUG(...) LOGD(__VA_ARGS__) +#define HCI_DEBUG(...) ALOGD(__VA_ARGS__) diff --git a/src/phHciNfc_NfcIPMgmt.c b/src/phHciNfc_NfcIPMgmt.c index 06ef2a8..68449be 100644 --- a/src/phHciNfc_NfcIPMgmt.c +++ b/src/phHciNfc_NfcIPMgmt.c @@ -1160,7 +1160,6 @@ phHciNfc_NfcIP_Info_Sequence ( rem_nfcipinfo->NfcIP_Info.Nfcip_Active = p_nfcipinfo->activation_mode; - if (NFCIP_INITIATOR == p_nfcipinfo->nfcip_type) { phNfc_sCompletionInfo_t CompInfo; @@ -1403,19 +1402,55 @@ phHciNfc_NfcIP_InfoUpdate( p_nfcipinfo->initiator_speed = (phHciNfc_eP2PSpeed_t) ((*reg_value >> NFCIP_COMM_INITIATOR_SHIFT) & NFCIP_COMM_FACTOR); + if (p_nfcipinfo->nfcip_type == NFCIP_INITIATOR) { + switch(p_nfcipinfo->initiator_speed) { + case phNfc_eDataRate_106: + ALOGI("I'm P2P %s Initiator @ 106 kb/s", p_nfcipinfo->activation_mode ? "Active" : "Passive"); + break; + case phNfc_eDataRate_212: + ALOGI("I'm P2P %s Initiator @ 212 kb/s", p_nfcipinfo->activation_mode ? "Active" : "Passive"); + break; + case phNfc_eDataRate_424: + ALOGI("I'm P2P %s Initiator @ 424 kb/s", p_nfcipinfo->activation_mode ? "Active" : "Passive"); + break; + } + } p_nfcipinfo->target_speed = (phHciNfc_eP2PSpeed_t) (*reg_value & NFCIP_COMM_FACTOR); + if (p_nfcipinfo->nfcip_type == NFCIP_TARGET) { + switch(p_nfcipinfo->target_speed) { + case phNfc_eDataRate_106: + ALOGI("I'm P2P %s Target @ 106 kb/s", p_nfcipinfo->activation_mode ? "Active" : "Passive"); + break; + case phNfc_eDataRate_212: + ALOGI("I'm P2P %s Target @ 212 kb/s", p_nfcipinfo->activation_mode ? "Active" : "Passive"); + break; + case phNfc_eDataRate_424: + ALOGI("I'm P2P %s Target @ 424 kb/s", p_nfcipinfo->activation_mode ? "Active" : "Passive"); + break; + } + } 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/phHciNfc_Sequence.c b/src/phHciNfc_Sequence.c index 1926c6c..400fa7a 100644 --- a/src/phHciNfc_Sequence.c +++ b/src/phHciNfc_Sequence.c @@ -1636,6 +1636,8 @@ phHciNfc_PollLoop_Sequence( { uint8_t speed = p_poll_config->NfcIP_Mode; + uint8_t targetSpeed = + p_poll_config->NfcIP_Target_Mode; switch(psHciContext->hci_seq) { case PL_DURATION_SEQ: @@ -1663,8 +1665,8 @@ phHciNfc_PollLoop_Sequence( { #define NFCIP_ACTIVE_SHIFT 0x03U #define NFCIP_PASSIVE_MASK 0x07U - uint8_t mode = ( NXP_NFCIP_ACTIVE_DEFAULT << NFCIP_ACTIVE_SHIFT ) | - ( DEFAULT_NFCIP_TARGET_MODE_SUPPORT & NFCIP_PASSIVE_MASK ); + uint8_t mode = targetSpeed; + ALOGE("Setting target mode to 0x%02X", mode); status = phHciNfc_NfcIP_SetMode( psHciContext, pHwRef, NFCIP_TARGET, (uint8_t) mode ); @@ -1685,6 +1687,7 @@ phHciNfc_PollLoop_Sequence( #if defined (ENABLE_P2P) && defined (INITIATOR_SPEED) case INITIATOR_SPEED_SEQ: { + ALOGE("Setting initiator mode to 0x%02X", speed); status = phHciNfc_NfcIP_SetMode( psHciContext, pHwRef, NFCIP_INITIATOR, (uint8_t) (speed & DEFAULT_NFCIP_INITIATOR_MODE_SUPPORT)); diff --git a/src/phLibNfc.c b/src/phLibNfc.c index 92bdc40..1012acb 100644 --- a/src/phLibNfc.c +++ b/src/phLibNfc.c @@ -870,7 +870,7 @@ NFCSTATUS phLibNfc_Mgt_GetstackCapabilities( /* Check the firmware version */ if (nxp_nfc_full_version == NULL) { // Couldn't load firmware, just pretend we're up to date. - LOGW("Firmware image not available: this device might be running old NFC firmware!"); + ALOGW("Firmware image not available: this device might be running old NFC firmware!"); phLibNfc_StackCapabilities->psDevCapabilities.firmware_update_info = 0; } else { phLibNfc_StackCapabilities->psDevCapabilities.firmware_update_info = memcmp(phLibNfc_StackCapabilities->psDevCapabilities.full_version, nxp_nfc_full_version, diff --git a/src/phLibNfc.h b/src/phLibNfc.h index 8621361..e4e41cf 100644 --- a/src/phLibNfc.h +++ b/src/phLibNfc.h @@ -2577,7 +2577,9 @@ extern NFCSTATUS phLibNfc_Llcp_GetRemoteInfo( phLibNfc_Handle * must provide a working buffer to the socket in order to handle incoming data. This buffer * must be large enough to fit the receive window (RW * MIU), the remaining space being * used as a linear buffer to store incoming data as a stream. Data will be readable later -* using the phLibNfc_Llcp_Recv function. +* using the phLibNfc_Llcp_Recv function. If the socket is connectionless, the caller may +* provide a working buffer to the socket in order to bufferize as many packets as the buffer +* can contain (each packet needs MIU + 1 bytes). * The options and working buffer are not required if the socket is used as a listening socket, * since it cannot be directly used for communication. * @@ -2611,6 +2613,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 +2729,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 +2743,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 +2761,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 +2776,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_SE.c b/src/phLibNfc_SE.c index 968c239..2cdb24e 100644 --- a/src/phLibNfc_SE.c +++ b/src/phLibNfc_SE.c @@ -665,81 +665,80 @@ NFCSTATUS phLibNfc_SE_SetMode ( phLibNfc_Handle hSE_Handle, */ STATIC void phLibNfc_SE_SetMode_cb(void *context, NFCSTATUS status) { - pphLibNfc_LibContext_t pLibContext=(pphLibNfc_LibContext_t)context; + /* Note that we don't use the passed in context here; + * the reason is that there are race-conditions around + * the place where this context is stored (mostly in combination + * with LLCP), and we may actually get the wrong context. + * Since this callback always uses the global context + * we don't need the passed in context anyway. + */ + pphLibNfc_LibContext_t pLibContext=gpphLibContext; pphLibNfc_SE_SetModeRspCb_t pUpperLayerCb=NULL; void *pUpperContext=NULL; phLibNfc_Handle hSeHandle=0; uint8_t TempState=FALSE; - if(pLibContext != gpphLibContext) + if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) { - /*wrong context returned*/ - phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); + /*If shutdown is called in between allow shutdown to happen*/ + phLibNfc_Pending_Shutdown(); + status = NFCSTATUS_SHUTDOWN; } else { - if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) + if(status == NFCSTATUS_SUCCESS) { - /*If shutdown is called in between allow shutdown to happen*/ - phLibNfc_Pending_Shutdown(); - status = NFCSTATUS_SHUTDOWN; - } - else - { - if(status == NFCSTATUS_SUCCESS) - { - hSeHandle = pLibContext->sSeContext.hSetemp; + hSeHandle = pLibContext->sSeContext.hSetemp; - if(hSeHandle == sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement) + if(hSeHandle == sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement) + { + if(TRUE==pLibContext->sCardEmulCfg.config.uiccEmuCfg.enableUicc) { - if(TRUE==pLibContext->sCardEmulCfg.config.uiccEmuCfg.enableUicc) - { - /*If Activation mode was virtual allow external reader to see it*/ - pLibContext->sSeContext.uUiccActivate = TRUE; - sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_CurrentState = phLibNfc_SE_Active; - } - else - { - /*If Activation mode was wired don't allow external reader to see it*/ - pLibContext->sSeContext.uUiccActivate = FALSE; - sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_CurrentState = - phLibNfc_SE_Inactive; - } - status = NFCSTATUS_SUCCESS; - TempState = pLibContext->sSeContext.uUiccActivate; + /*If Activation mode was virtual allow external reader to see it*/ + pLibContext->sSeContext.uUiccActivate = TRUE; + sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_CurrentState = phLibNfc_SE_Active; } - else if (hSeHandle==sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement) + else { - if(TRUE==pLibContext->sCardEmulCfg.config.smartMxCfg.enableEmulation) - { - /*If Activation mode was virtual allow external reader to see it*/ - pLibContext->sSeContext.uSmxActivate = TRUE; - sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_CurrentState = - phLibNfc_SE_Active; - } - else - { - /*If Activation mode was wired don't allow external reader to see it*/ - pLibContext->sSeContext.uSmxActivate = FALSE; - sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_CurrentState= - phLibNfc_SE_Inactive; - } - status = NFCSTATUS_SUCCESS; - TempState = pLibContext->sSeContext.uSmxActivate; + /*If Activation mode was wired don't allow external reader to see it*/ + pLibContext->sSeContext.uUiccActivate = FALSE; + sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_CurrentState = + phLibNfc_SE_Inactive; + } + status = NFCSTATUS_SUCCESS; + TempState = pLibContext->sSeContext.uUiccActivate; + } + else if (hSeHandle==sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement) + { + if(TRUE==pLibContext->sCardEmulCfg.config.smartMxCfg.enableEmulation) + { + /*If Activation mode was virtual allow external reader to see it*/ + pLibContext->sSeContext.uSmxActivate = TRUE; + sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_CurrentState = + phLibNfc_SE_Active; } else { - status = NFCSTATUS_FAILED; + /*If Activation mode was wired don't allow external reader to see it*/ + pLibContext->sSeContext.uSmxActivate = FALSE; + sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_CurrentState= + phLibNfc_SE_Inactive; } + status = NFCSTATUS_SUCCESS; + TempState = pLibContext->sSeContext.uSmxActivate; } else { status = NFCSTATUS_FAILED; } - pLibContext->status.GenCb_pending_status = FALSE; } - + else + { + status = NFCSTATUS_FAILED; + } + pLibContext->status.GenCb_pending_status = FALSE; } + pUpperLayerCb = pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCb; pUpperContext = pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCtxt; pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCb = NULL; 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 ); diff --git a/src/phLlcNfc_Interface.c b/src/phLlcNfc_Interface.c index 175462d..7f3336d 100644 --- a/src/phLlcNfc_Interface.c +++ b/src/phLlcNfc_Interface.c @@ -786,7 +786,7 @@ phLlcNfc_RdResp_Cb( else if (ps_frame_info->recv_error_count < PH_LLCNFC_MAX_REJ_RETRY_COUNT) { - LOGW("LLC bad crc"); + ALOGW("LLC bad crc"); PH_LLCNFC_PRINT("CRC ERROR RECVD \n"); PH_LLCNFC_DEBUG("RECV ERROR COUNT : 0x%02X\n", ps_frame_info->recv_error_count); @@ -807,7 +807,7 @@ phLlcNfc_RdResp_Cb( } else { - LOGE("max LLC retries exceeded, stack restart"); + ALOGE("max LLC retries exceeded, stack restart"); result = phLlcNfc_Interface_Read (ps_llc_ctxt, PH_LLCNFC_READWAIT_OFF, (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), @@ -832,7 +832,7 @@ phLlcNfc_RdResp_Cb( else if (ps_frame_info->recv_error_count >= PH_LLCNFC_MAX_REJ_RETRY_COUNT) { - LOGE("max LLC retries exceeded, stack restart"); + ALOGE("max LLC retries exceeded, stack restart"); result = phLlcNfc_Interface_Read (ps_llc_ctxt, PH_LLCNFC_READWAIT_OFF, (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), @@ -855,7 +855,7 @@ phLlcNfc_RdResp_Cb( (PH_LLCNFC_MAX_BUFLEN_RECV_SEND > pCompInfo->length) && (pCompInfo->length != ps_recv_pkt->s_llcbuf.llc_length_byte)) { - LOGE("bad LLC length1 %d", pCompInfo->length); + ALOGE("bad LLC length1 %d", pCompInfo->length); ps_frame_info->recv_error_count = (uint8_t) (ps_frame_info->recv_error_count + 1); libnfc_llc_error_count++; @@ -883,7 +883,7 @@ phLlcNfc_RdResp_Cb( value is greater than (0x21 - 1), then pend a read to get 1 byte again */ - LOGW("bad LLC length byte %x\n", *(pCompInfo->buffer)); + ALOGW("bad LLC length byte %x\n", *(pCompInfo->buffer)); ps_frame_info->recv_error_count = (uint8_t) (ps_frame_info->recv_error_count + 1); libnfc_llc_error_count++; @@ -895,7 +895,7 @@ phLlcNfc_RdResp_Cb( } else { - LOGW("unknown LLC error1"); + ALOGW("unknown LLC error1"); ps_frame_info->recv_error_count = (uint8_t) (ps_frame_info->recv_error_count + 1); libnfc_llc_error_count++; @@ -919,7 +919,7 @@ phLlcNfc_RdResp_Cb( } } else if (NFCSTATUS_READ_FAILED == pCompInfo->status) { // partial read - try reading the length byte again - LOGW("LLC length mis-match\n"); + ALOGW("LLC length mis-match\n"); ps_frame_info->recv_error_count = (uint8_t) (ps_frame_info->recv_error_count + 1); libnfc_llc_error_count++; @@ -931,7 +931,7 @@ phLlcNfc_RdResp_Cb( } else { - LOGW("unknown LLC error2"); + ALOGW("unknown LLC error2"); ps_frame_info->recv_error_count = (uint8_t) (ps_frame_info->recv_error_count + 1); libnfc_llc_error_count++; |