Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2010 NXP Semiconductors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /**
     18  * \file  phFriNfc_LlcpTransport_Connectionless.c
     19  * \brief
     20  *
     21  * Project: NFC-FRI
     22  *
     23  */
     24 /*include files*/
     25 #include <phOsalNfc.h>
     26 #include <phLibNfcStatus.h>
     27 #include <phLibNfc.h>
     28 #include <phNfcLlcpTypes.h>
     29 #include <phFriNfc_LlcpTransport.h>
     30 #include <phFriNfc_Llcp.h>
     31 
     32 /* TODO: comment function Handle_Connectionless_IncommingFrame */
     33 void Handle_Connectionless_IncommingFrame(phFriNfc_LlcpTransport_t      *pLlcpTransport,
     34                                           phNfc_sData_t                 *psData,
     35                                           uint8_t                       dsap,
     36                                           uint8_t                       ssap)
     37 {
     38    uint8_t i=0;
     39 
     40    for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++)
     41    {
     42       /* Test if a socket is registered to get this packet */
     43       if(pLlcpTransport->pSocketTable[i].socket_sSap == dsap && pLlcpTransport->pSocketTable[i].bSocketRecvPending == TRUE)
     44       {
     45          /* Reset the RecvPending variable */
     46          pLlcpTransport->pSocketTable[i].bSocketRecvPending = FALSE;
     47 
     48          /* Copy the received buffer into the receive buffer */
     49          memcpy(pLlcpTransport->pSocketTable[i].sSocketRecvBuffer->buffer,psData->buffer,psData->length);
     50 
     51          /* Update the received length */
     52          *pLlcpTransport->pSocketTable[i].receivedLength = psData->length;
     53 
     54          /* call the Recv callback */
     55          pLlcpTransport->pSocketTable[i].pfSocketRecvFrom_Cb(pLlcpTransport->pSocketTable[i].pRecvContext,ssap,NFCSTATUS_SUCCESS);
     56          break;
     57       }
     58    }
     59 }
     60 
     61 /* TODO: comment function phFriNfc_LlcpTransport_Connectionless_SendTo_CB */
     62 static void phFriNfc_LlcpTransport_Connectionless_SendTo_CB(void*        pContext,
     63                                                             NFCSTATUS    status)
     64 {
     65    phFriNfc_LlcpTransport_Socket_t   *pLlcpSocket = (phFriNfc_LlcpTransport_Socket_t*)pContext;
     66 
     67    /* Reset the SendPending variable */
     68    pLlcpSocket->bSocketSendPending = FALSE;
     69 
     70    /* Call the send callback */
     71    pLlcpSocket->pfSocketSend_Cb(pLlcpSocket->pSendContext,status);
     72 
     73 }
     74 
     75 static void phFriNfc_LlcpTransport_Connectionless_Abort(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket)
     76 {
     77    if (pLlcpSocket->pfSocketSend_Cb != NULL)
     78    {
     79       pLlcpSocket->pfSocketSend_Cb(pLlcpSocket->pSendContext, NFCSTATUS_ABORTED);
     80       pLlcpSocket->pSendContext = NULL;
     81       pLlcpSocket->pfSocketSend_Cb = NULL;
     82    }
     83    if (pLlcpSocket->pfSocketRecvFrom_Cb != NULL)
     84    {
     85       pLlcpSocket->pfSocketRecvFrom_Cb(pLlcpSocket->pRecvContext, 0, NFCSTATUS_ABORTED);
     86       pLlcpSocket->pRecvContext = NULL;
     87       pLlcpSocket->pfSocketRecvFrom_Cb = NULL;
     88       pLlcpSocket->pfSocketRecv_Cb = NULL;
     89    }
     90    pLlcpSocket->pAcceptContext = NULL;
     91    pLlcpSocket->pfSocketAccept_Cb = NULL;
     92    pLlcpSocket->pListenContext = NULL;
     93    pLlcpSocket->pfSocketListen_Cb = NULL;
     94    pLlcpSocket->pConnectContext = NULL;
     95    pLlcpSocket->pfSocketConnect_Cb = NULL;
     96    pLlcpSocket->pDisonnectContext = NULL;
     97    pLlcpSocket->pfSocketDisconnect_Cb = NULL;
     98 }
     99 
    100 /**
    101 * \ingroup grp_fri_nfc
    102 * \brief <b>Close a socket on a LLCP-connectionless device</b>.
    103 *
    104 * This function closes a LLCP socket previously created using phFriNfc_LlcpTransport_Socket.
    105 *
    106 * \param[in]  pLlcpSocket                    A pointer to a phFriNfc_LlcpTransport_Socket_t.
    107 
    108 * \retval NFCSTATUS_SUCCESS                  Operation successful.
    109 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
    110 *                                            could not be properly interpreted.
    111 * \retval NFCSTATUS_FAILED                   Operation failed.
    112 */
    113 NFCSTATUS phFriNfc_LlcpTransport_Connectionless_Close(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket)
    114 {
    115    /* Reset the pointer to the socket closed */
    116    pLlcpSocket->eSocket_State                      = phFriNfc_LlcpTransportSocket_eSocketDefault;
    117    pLlcpSocket->eSocket_Type                       = phFriNfc_LlcpTransport_eDefaultType;
    118    pLlcpSocket->pContext                           = NULL;
    119    pLlcpSocket->pSocketErrCb                       = NULL;
    120    pLlcpSocket->socket_sSap                        = PHFRINFC_LLCP_SAP_DEFAULT;
    121    pLlcpSocket->socket_dSap                        = PHFRINFC_LLCP_SAP_DEFAULT;
    122    pLlcpSocket->bSocketRecvPending                 = FALSE;
    123    pLlcpSocket->bSocketSendPending                 = FALSE;
    124    pLlcpSocket->bSocketListenPending               = FALSE;
    125    pLlcpSocket->bSocketDiscPending                 = FALSE;
    126    pLlcpSocket->RemoteBusyConditionInfo            = FALSE;
    127    pLlcpSocket->ReceiverBusyCondition              = FALSE;
    128    pLlcpSocket->socket_VS                          = 0;
    129    pLlcpSocket->socket_VSA                         = 0;
    130    pLlcpSocket->socket_VR                          = 0;
    131    pLlcpSocket->socket_VRA                         = 0;
    132 
    133    phFriNfc_LlcpTransport_Connectionless_Abort(pLlcpSocket);
    134 
    135    memset(&pLlcpSocket->sSocketOption, 0x00, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));
    136 
    137    if (pLlcpSocket->sServiceName.buffer != NULL) {
    138        phOsalNfc_FreeMemory(pLlcpSocket->sServiceName.buffer);
    139    }
    140    pLlcpSocket->sServiceName.buffer = NULL;
    141    pLlcpSocket->sServiceName.length = 0;
    142 
    143    return NFCSTATUS_SUCCESS;
    144 }
    145 
    146 /**
    147 * \ingroup grp_fri_nfc
    148 * \brief <b>Send data on a socket to a given destination SAP</b>.
    149 *
    150 * This function is used to write data on a socket to a given destination SAP.
    151 * This function can only be called on a connectionless socket.
    152 *
    153 *
    154 * \param[in]  pLlcpSocket        A pointer to a LlcpSocket created.
    155 * \param[in]  nSap               The destination SAP.
    156 * \param[in]  psBuffer           The buffer containing the data to send.
    157 * \param[in]  pSend_RspCb        The callback to be called when the
    158 *                                operation is completed.
    159 * \param[in]  pContext           Upper layer context to be returned in
    160 *                                the callback.
    161 *
    162 * \retval NFCSTATUS_SUCCESS                  Operation successful.
    163 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
    164 *                                            could not be properly interpreted.
    165 * \retval NFCSTATUS_PENDING                  Reception operation is in progress,
    166 *                                            pSend_RspCb will be called upon completion.
    167 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
    168 *                                            a valid type to perform the requsted operation.
    169 * \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
    170 * \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
    171 * \retval NFCSTATUS_FAILED                   Operation failed.
    172 */
    173 NFCSTATUS phFriNfc_LlcpTransport_Connectionless_SendTo(phFriNfc_LlcpTransport_Socket_t             *pLlcpSocket,
    174                                                        uint8_t                                     nSap,
    175                                                        phNfc_sData_t*                              psBuffer,
    176                                                        pphFriNfc_LlcpTransportSocketSendCb_t       pSend_RspCb,
    177                                                        void*                                       pContext)
    178 {
    179    NFCSTATUS status = NFCSTATUS_SUCCESS;
    180 
    181    /* Store send callback  and context*/
    182    pLlcpSocket->pfSocketSend_Cb = pSend_RspCb;
    183    pLlcpSocket->pSendContext    = pContext;
    184 
    185    /* Test if a send is pending with this socket */
    186    if(pLlcpSocket->bSocketSendPending == TRUE)
    187    {
    188       status = NFCSTATUS_FAILED;
    189       pLlcpSocket->pfSocketSend_Cb(pLlcpSocket->pSendContext,status);
    190    }
    191    else
    192    {
    193       /* Fill the psLlcpHeader stuture with the DSAP,PTYPE and the SSAP */
    194       pLlcpSocket->sLlcpHeader.dsap  = nSap;
    195       pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_UI;
    196       pLlcpSocket->sLlcpHeader.ssap  = pLlcpSocket->socket_sSap;
    197 
    198       pLlcpSocket->bSocketSendPending = TRUE;
    199 
    200       /* Send to data to the approiate socket */
    201       status =  phFriNfc_Llcp_Send(pLlcpSocket->psTransport->pLlcp,
    202                                    &pLlcpSocket->sLlcpHeader,
    203                                    NULL,
    204                                    psBuffer,
    205                                    phFriNfc_LlcpTransport_Connectionless_SendTo_CB,
    206                                    pLlcpSocket);
    207    }
    208 
    209    return status;
    210 }
    211 
    212 
    213  /**
    214 * \ingroup grp_lib_nfc
    215 * \brief <b>Read data on a socket and get the source SAP</b>.
    216 *
    217 * This function is the same as phLibNfc_Llcp_Recv, except that the callback includes
    218 * the source SAP. This functions can only be called on a connectionless socket.
    219 *
    220 *
    221 * \param[in]  pLlcpSocket        A pointer to a LlcpSocket created.
    222 * \param[in]  psBuffer           The buffer receiving the data.
    223 * \param[in]  pRecv_RspCb        The callback to be called when the
    224 *                                operation is completed.
    225 * \param[in]  pContext           Upper layer context to be returned in
    226 *                                the callback.
    227 *
    228 * \retval NFCSTATUS_SUCCESS                  Operation successful.
    229 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
    230 *                                            could not be properly interpreted.
    231 * \retval NFCSTATUS_PENDING                  Reception operation is in progress,
    232 *                                            pRecv_RspCb will be called upon completion.
    233 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
    234 *                                            a valid type to perform the requsted operation.
    235 * \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
    236 * \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
    237 * \retval NFCSTATUS_FAILED                   Operation failed.
    238 */
    239 NFCSTATUS phLibNfc_LlcpTransport_Connectionless_RecvFrom(phFriNfc_LlcpTransport_Socket_t                   *pLlcpSocket,
    240                                                          phNfc_sData_t*                                    psBuffer,
    241                                                          pphFriNfc_LlcpTransportSocketRecvFromCb_t         pRecv_Cb,
    242                                                          void                                              *pContext)
    243 {
    244    NFCSTATUS status = NFCSTATUS_PENDING;
    245 
    246    if(pLlcpSocket->bSocketRecvPending)
    247    {
    248       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_REJECTED);
    249    }
    250    else
    251    {
    252       /* Store the callback and context*/
    253       pLlcpSocket->pfSocketRecvFrom_Cb  = pRecv_Cb;
    254       pLlcpSocket->pRecvContext         = pContext;
    255 
    256       /* Store the pointer to the receive buffer */
    257       pLlcpSocket->sSocketRecvBuffer   =  psBuffer;
    258       pLlcpSocket->receivedLength      =  &psBuffer->length;
    259 
    260       /* Set RecvPending to TRUE */
    261       pLlcpSocket->bSocketRecvPending = TRUE;
    262    }
    263    return status;
    264 }
    265