• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.c
19  * \brief
20  *
21  * Project: NFC-FRI
22  *
23  */
24 
25 /*include files*/
26 #include <phOsalNfc.h>
27 #include <phLibNfcStatus.h>
28 #include <phLibNfc.h>
29 #include <phNfcLlcpTypes.h>
30 #include <phFriNfc_Llcp.h>
31 #include <phFriNfc_LlcpTransport.h>
32 #include <phFriNfc_LlcpTransport_Connectionless.h>
33 #include <phFriNfc_LlcpTransport_Connection.h>
34 
35 /* local macros */
36 
37 /* Check if (a <= x < b) */
38 #define IS_BETWEEN(x, a, b) (((x)>=(a)) && ((x)<(b)))
39 
40 
phFriNfc_LlcpTransport_AutoBind(phFriNfc_LlcpTransport_Socket_t * pSocket)41 static NFCSTATUS phFriNfc_LlcpTransport_AutoBind(phFriNfc_LlcpTransport_Socket_t *pSocket)
42 {
43    uint8_t i;
44    uint8_t sap;
45    phFriNfc_LlcpTransport_Socket_t* pSocketTable = pSocket->psTransport->pSocketTable;
46 
47    /* Try all possible SAPs */
48    for(sap=PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST ; sap<PHFRINFC_LLCP_SAP_NUMBER ; sap++)
49    {
50       /* Go through socket list to check if current SAP is in use */
51       for(i=0 ; i<PHFRINFC_LLCP_NB_SOCKET_MAX ; i++)
52       {
53          if((pSocketTable[i].eSocket_State >= phFriNfc_LlcpTransportSocket_eSocketBound) &&
54             (pSocketTable[i].socket_sSap == sap))
55          {
56             /* SAP is already in use */
57             break;
58          }
59       }
60 
61       if (i >= PHFRINFC_LLCP_NB_SOCKET_MAX)
62       {
63          /* No socket is using current SAP, proceed with binding */
64          pSocket->socket_sSap = sap;
65          pSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketBound;
66          return NFCSTATUS_SUCCESS;
67       }
68    }
69 
70    /* If we reach this point, it means that no SAP is free */
71    return NFCSTATUS_INSUFFICIENT_RESOURCES;
72 }
73 
74 /* TODO: comment function Transport recv CB */
phFriNfc_LlcpTransport__Recv_CB(void * pContext,phNfc_sData_t * psData,NFCSTATUS status)75 static void phFriNfc_LlcpTransport__Recv_CB(void            *pContext,
76                                             phNfc_sData_t   *psData,
77                                             NFCSTATUS        status)
78 {
79    phFriNfc_Llcp_sPacketHeader_t   sLlcpLocalHeader;
80    uint8_t   dsap;
81    uint8_t   ptype;
82    uint8_t   ssap;
83 
84    phFriNfc_LlcpTransport_t* pLlcpTransport = (phFriNfc_LlcpTransport_t*)pContext;
85 
86    if(status != NFCSTATUS_SUCCESS)
87    {
88       pLlcpTransport->LinkStatusError = TRUE;
89    }
90    else
91    {
92       phFriNfc_Llcp_Buffer2Header( psData->buffer,0x00, &sLlcpLocalHeader);
93 
94       dsap  = (uint8_t)sLlcpLocalHeader.dsap;
95       ptype = (uint8_t)sLlcpLocalHeader.ptype;
96       ssap  = (uint8_t)sLlcpLocalHeader.ssap;
97 
98       /* Update the length value (without the header length) */
99       psData->length = psData->length - PHFRINFC_LLCP_PACKET_HEADER_SIZE;
100 
101       /* Update the buffer pointer */
102       psData->buffer = psData->buffer + PHFRINFC_LLCP_PACKET_HEADER_SIZE;
103 
104       switch(ptype)
105       {
106       /* Connectionless */
107       case PHFRINFC_LLCP_PTYPE_UI:
108          {
109             Handle_Connectionless_IncommingFrame(pLlcpTransport,
110                                                  psData,
111                                                  dsap,
112                                                  ssap);
113          }break;
114 
115       /* Connection oriented */
116       /* NOTE: forward reserved PTYPE to enable FRMR sending */
117       case PHFRINFC_LLCP_PTYPE_CONNECT:
118       case PHFRINFC_LLCP_PTYPE_CC:
119       case PHFRINFC_LLCP_PTYPE_DISC:
120       case PHFRINFC_LLCP_PTYPE_DM:
121       case PHFRINFC_LLCP_PTYPE_I:
122       case PHFRINFC_LLCP_PTYPE_RR:
123       case PHFRINFC_LLCP_PTYPE_RNR:
124       case PHFRINFC_LLCP_PTYPE_FRMR:
125       case PHFRINFC_LLCP_PTYPE_RESERVED1:
126       case PHFRINFC_LLCP_PTYPE_RESERVED2:
127       case PHFRINFC_LLCP_PTYPE_RESERVED3:
128       case PHFRINFC_LLCP_PTYPE_RESERVED4:
129          {
130             Handle_ConnectionOriented_IncommingFrame(pLlcpTransport,
131                                                      psData,
132                                                      dsap,
133                                                      ptype,
134                                                      ssap);
135          }break;
136       default:
137          {
138 
139          }break;
140       }
141 
142       /*Restart the Receive Loop */
143       status  = phFriNfc_Llcp_Recv(pLlcpTransport->pLlcp,
144                                    phFriNfc_LlcpTransport__Recv_CB,
145                                    pLlcpTransport);
146    }
147 }
148 
149 
150 /* TODO: comment function Transport reset */
phFriNfc_LlcpTransport_Reset(phFriNfc_LlcpTransport_t * pLlcpTransport,phFriNfc_Llcp_t * pLlcp)151 NFCSTATUS phFriNfc_LlcpTransport_Reset (phFriNfc_LlcpTransport_t      *pLlcpTransport,
152                                         phFriNfc_Llcp_t               *pLlcp)
153 {
154    NFCSTATUS status = NFCSTATUS_SUCCESS;
155    uint8_t i;
156 
157    /* Check for NULL pointers */
158    if(pLlcpTransport == NULL || pLlcp == NULL)
159    {
160       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
161    }
162    else
163    {
164       /* Reset Transport structure */
165       pLlcpTransport->pLlcp            = pLlcp;
166       pLlcpTransport->LinkStatusError  = FALSE;
167       pLlcpTransport->bSendPending     = FALSE;
168       pLlcpTransport->bRecvPending     = FALSE;
169       pLlcpTransport->bDmPending       = FALSE;
170       pLlcpTransport->bFrmrPending     = FALSE;
171       pLlcpTransport->socketIndex      = FALSE;
172       pLlcpTransport->LinkStatusError  = 0;
173 
174 
175       /* Reset all the socket info in the table */
176       for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++)
177       {
178          pLlcpTransport->pSocketTable[i].eSocket_State                  = phFriNfc_LlcpTransportSocket_eSocketDefault;
179          pLlcpTransport->pSocketTable[i].eSocket_Type                   = phFriNfc_LlcpTransport_eDefaultType;
180          pLlcpTransport->pSocketTable[i].index                          = i;
181          pLlcpTransport->pSocketTable[i].pContext                       = NULL;
182          pLlcpTransport->pSocketTable[i].pListenContext                 = NULL;
183          pLlcpTransport->pSocketTable[i].pAcceptContext                 = NULL;
184          pLlcpTransport->pSocketTable[i].pRejectContext                 = NULL;
185          pLlcpTransport->pSocketTable[i].pConnectContext                = NULL;
186          pLlcpTransport->pSocketTable[i].pDisonnectContext              = NULL;
187          pLlcpTransport->pSocketTable[i].pSendContext                   = NULL;
188          pLlcpTransport->pSocketTable[i].pRecvContext                   = NULL;
189          pLlcpTransport->pSocketTable[i].pSocketErrCb                   = NULL;
190          pLlcpTransport->pSocketTable[i].bufferLinearLength             = 0;
191          pLlcpTransport->pSocketTable[i].bufferSendMaxLength            = 0;
192          pLlcpTransport->pSocketTable[i].bufferRwMaxLength              = 0;
193          pLlcpTransport->pSocketTable[i].ReceiverBusyCondition          = FALSE;
194          pLlcpTransport->pSocketTable[i].RemoteBusyConditionInfo        = FALSE;
195          pLlcpTransport->pSocketTable[i].socket_sSap                    = PHFRINFC_LLCP_SAP_DEFAULT;
196          pLlcpTransport->pSocketTable[i].socket_dSap                    = PHFRINFC_LLCP_SAP_DEFAULT;
197          pLlcpTransport->pSocketTable[i].bSocketRecvPending             = FALSE;
198          pLlcpTransport->pSocketTable[i].bSocketSendPending             = FALSE;
199          pLlcpTransport->pSocketTable[i].bSocketListenPending           = FALSE;
200          pLlcpTransport->pSocketTable[i].bSocketDiscPending             = FALSE;
201          pLlcpTransport->pSocketTable[i].bSocketConnectPending          = FALSE;
202          pLlcpTransport->pSocketTable[i].bSocketAcceptPending           = FALSE;
203          pLlcpTransport->pSocketTable[i].bSocketRRPending               = FALSE;
204          pLlcpTransport->pSocketTable[i].bSocketRNRPending              = FALSE;
205          pLlcpTransport->pSocketTable[i].psTransport                    = pLlcpTransport;
206          pLlcpTransport->pSocketTable[i].pfSocketSend_Cb                = NULL;
207          pLlcpTransport->pSocketTable[i].pfSocketRecv_Cb                = NULL;
208          pLlcpTransport->pSocketTable[i].pfSocketRecvFrom_Cb            = NULL;
209          pLlcpTransport->pSocketTable[i].pfSocketListen_Cb              = NULL;
210          pLlcpTransport->pSocketTable[i].pfSocketConnect_Cb             = NULL;
211          pLlcpTransport->pSocketTable[i].pfSocketDisconnect_Cb          = NULL;
212          pLlcpTransport->pSocketTable[i].socket_VS                      = 0;
213          pLlcpTransport->pSocketTable[i].socket_VSA                     = 0;
214          pLlcpTransport->pSocketTable[i].socket_VR                      = 0;
215          pLlcpTransport->pSocketTable[i].socket_VRA                     = 0;
216          pLlcpTransport->pSocketTable[i].remoteRW                       = 0;
217          pLlcpTransport->pSocketTable[i].localRW                        = 0;
218          pLlcpTransport->pSocketTable[i].remoteMIU                      = 0;
219          pLlcpTransport->pSocketTable[i].localMIUX                      = 0;
220          pLlcpTransport->pSocketTable[i].index                          = 0;
221          pLlcpTransport->pSocketTable[i].indexRwRead                    = 0;
222          pLlcpTransport->pSocketTable[i].indexRwWrite                   = 0;
223 
224          memset(&pLlcpTransport->pSocketTable[i].sSocketOption, 0x00, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));
225 
226          if (pLlcpTransport->pSocketTable[i].sServiceName.buffer != NULL) {
227             phOsalNfc_FreeMemory(pLlcpTransport->pSocketTable[i].sServiceName.buffer);
228          }
229          pLlcpTransport->pSocketTable[i].sServiceName.buffer = NULL;
230          pLlcpTransport->pSocketTable[i].sServiceName.length = 0;
231       }
232 
233       /* Start The Receive Loop */
234       status  = phFriNfc_Llcp_Recv(pLlcpTransport->pLlcp,
235                                    phFriNfc_LlcpTransport__Recv_CB,
236                                    pLlcpTransport);
237    }
238    return status;
239 }
240 
241 /* TODO: comment function Transport CloseAll */
phFriNfc_LlcpTransport_CloseAll(phFriNfc_LlcpTransport_t * pLlcpTransport)242 NFCSTATUS phFriNfc_LlcpTransport_CloseAll (phFriNfc_LlcpTransport_t *pLlcpTransport)
243 {
244    NFCSTATUS status = NFCSTATUS_SUCCESS;
245    uint8_t i;
246 
247    /* Check for NULL pointers */
248    if(pLlcpTransport == NULL)
249    {
250       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
251    }
252 
253    /* Close all sockets */
254    for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++)
255    {
256       if(pLlcpTransport->pSocketTable[i].eSocket_Type == phFriNfc_LlcpTransport_eConnectionOriented)
257       {
258          switch(pLlcpTransport->pSocketTable[i].eSocket_State)
259          {
260          case phFriNfc_LlcpTransportSocket_eSocketConnected:
261          case phFriNfc_LlcpTransportSocket_eSocketConnecting:
262          case phFriNfc_LlcpTransportSocket_eSocketAccepted:
263          case phFriNfc_LlcpTransportSocket_eSocketDisconnected:
264          case phFriNfc_LlcpTransportSocket_eSocketDisconnecting:
265          case phFriNfc_LlcpTransportSocket_eSocketRejected:
266             phFriNfc_LlcpTransport_Close(&pLlcpTransport->pSocketTable[i]);
267             break;
268          default: break;
269          }
270       }
271       else
272       {
273          phFriNfc_LlcpTransport_Close(&pLlcpTransport->pSocketTable[i]);
274       }
275    }
276    return status;
277 }
278 
279 
280 /**
281 * \ingroup grp_lib_nfc
282 * \brief <b>Get the local options of a socket</b>.
283 *
284 * This function returns the local options (maximum packet size and receive window size) used
285 * for a given connection-oriented socket. This function shall not be used with connectionless
286 * sockets.
287 *
288 * \param[out] pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
289 * \param[in]  psLocalOptions        A pointer to be filled with the local options of the socket.
290 *
291 * \retval NFCSTATUS_SUCCESS                  Operation successful.
292 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
293 *                                            could not be properly interpreted.
294 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
295 *                                            a valid type to perform the requsted operation.
296 * \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
297 * \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
298 * \retval NFCSTATUS_FAILED                   Operation failed.
299 */
phFriNfc_LlcpTransport_SocketGetLocalOptions(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket,phLibNfc_Llcp_sSocketOptions_t * psLocalOptions)300 NFCSTATUS phFriNfc_LlcpTransport_SocketGetLocalOptions(phFriNfc_LlcpTransport_Socket_t  *pLlcpSocket,
301                                                        phLibNfc_Llcp_sSocketOptions_t   *psLocalOptions)
302 {
303    NFCSTATUS status = NFCSTATUS_SUCCESS;
304 
305    /* Check for NULL pointers */
306    if (pLlcpSocket == NULL || psLocalOptions == NULL)
307    {
308       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
309    }
310    /*  Test the socket type */
311    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
312    {
313       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
314    }
315    /*  Test the socket state */
316    else if(pLlcpSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketDefault)
317    {
318       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
319    }
320    else
321    {
322      status = phFriNfc_LlcpTransport_ConnectionOriented_SocketGetLocalOptions(pLlcpSocket,
323                                                                               psLocalOptions);
324    }
325 
326    return status;
327 }
328 
329 
330 /**
331 * \ingroup grp_lib_nfc
332 * \brief <b>Get the local options of a socket</b>.
333 *
334 * This function returns the remote options (maximum packet size and receive window size) used
335 * for a given connection-oriented socket. This function shall not be used with connectionless
336 * sockets.
337 *
338 * \param[out] pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
339 * \param[in]  psRemoteOptions       A pointer to be filled with the remote options of the socket.
340 *
341 * \retval NFCSTATUS_SUCCESS                  Operation successful.
342 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
343 *                                            could not be properly interpreted.
344 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
345 *                                            a valid type to perform the requsted operation.
346 * \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
347 * \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
348 * \retval NFCSTATUS_FAILED                   Operation failed.
349 */
phFriNfc_LlcpTransport_SocketGetRemoteOptions(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket,phLibNfc_Llcp_sSocketOptions_t * psRemoteOptions)350 NFCSTATUS phFriNfc_LlcpTransport_SocketGetRemoteOptions(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket,
351                                                         phLibNfc_Llcp_sSocketOptions_t*    psRemoteOptions)
352 {
353    NFCSTATUS status = NFCSTATUS_SUCCESS;
354 
355    /* Check for NULL pointers */
356    if (pLlcpSocket == NULL || psRemoteOptions == NULL)
357    {
358       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
359    }
360    /*  Test the socket type */
361    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
362    {
363       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
364    }
365    /*  Test the socket state */
366    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketConnected)
367    {
368       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
369    }
370    else
371    {
372       status = phFriNfc_LlcpTransport_ConnectionOriented_SocketGetRemoteOptions(pLlcpSocket,
373                                                                                 psRemoteOptions);
374    }
375 
376    return status;
377 }
378 
379  /**
380 * \ingroup grp_fri_nfc
381 * \brief <b>Create a socket on a LLCP-connected device</b>.
382 *
383 * This function creates a socket for a given LLCP link. Sockets can be of two types :
384 * connection-oriented and connectionless. If the socket is connection-oriented, the caller
385 * must provide a working buffer to the socket in order to handle incoming data. This buffer
386 * must be large enough to fit the receive window (RW * MIU), the remaining space being
387 * used as a linear buffer to store incoming data as a stream. Data will be readable later
388 * using the phLibNfc_LlcpTransport_Recv function.
389 * The options and working buffer are not required if the socket is used as a listening socket,
390 * since it cannot be directly used for communication.
391 *
392 * \param[in]  pLlcpSocketTable      A pointer to a table of PHFRINFC_LLCP_NB_SOCKET_DEFAULT sockets.
393 * \param[in]  eType                 The socket type.
394 * \param[in]  psOptions             The options to be used with the socket.
395 * \param[in]  psWorkingBuffer       A working buffer to be used by the library.
396 * \param[out] pLlcpSocket           A pointer on the socket to be filled with a
397                                     socket found on the socket table.
398 * \param[in]  pErr_Cb               The callback to be called each time the socket
399 *                                   is in error.
400 * \param[in]  pContext              Upper layer context to be returned in the callback.
401 *
402 * \retval NFCSTATUS_SUCCESS                  Operation successful.
403 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
404 *                                            could not be properly interpreted.
405 * \retval NFCSTATUS_BUFFER_TOO_SMALL         The working buffer is too small for the MIU and RW
406 *                                            declared in the options.
407 * \retval NFCSTATUS_INSUFFICIENT_RESOURCES   No more socket handle available.
408 * \retval NFCSTATUS_FAILED                   Operation failed.
409 * */
phFriNfc_LlcpTransport_Socket(phFriNfc_LlcpTransport_t * pLlcpTransport,phFriNfc_LlcpTransport_eSocketType_t eType,phFriNfc_LlcpTransport_sSocketOptions_t * psOptions,phNfc_sData_t * psWorkingBuffer,phFriNfc_LlcpTransport_Socket_t ** pLlcpSocket,pphFriNfc_LlcpTransportSocketErrCb_t pErr_Cb,void * pContext)410 NFCSTATUS phFriNfc_LlcpTransport_Socket(phFriNfc_LlcpTransport_t                  *pLlcpTransport,
411                                         phFriNfc_LlcpTransport_eSocketType_t      eType,
412                                         phFriNfc_LlcpTransport_sSocketOptions_t   *psOptions,
413                                         phNfc_sData_t                             *psWorkingBuffer,
414                                         phFriNfc_LlcpTransport_Socket_t           **pLlcpSocket,
415                                         pphFriNfc_LlcpTransportSocketErrCb_t      pErr_Cb,
416                                         void                                      *pContext)
417 {
418    NFCSTATUS status = NFCSTATUS_SUCCESS;
419    phFriNfc_Llcp_sLinkParameters_t  LlcpLinkParamInfo;
420    uint8_t index=0;
421    uint8_t cpt;
422 
423    /* Check for NULL pointers */
424    if (((NULL == psOptions) && (eType != phFriNfc_LlcpTransport_eConnectionLess)) || ((psWorkingBuffer == NULL) && (eType != phFriNfc_LlcpTransport_eConnectionLess)) || pLlcpSocket == NULL || pErr_Cb == NULL || pContext == NULL || pLlcpTransport == NULL)
425    {
426       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
427       return status;
428    }
429    /*  Test the socket type*/
430    else if(eType != phFriNfc_LlcpTransport_eConnectionOriented && eType != phFriNfc_LlcpTransport_eConnectionLess)
431    {
432       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
433       return status;
434    }
435 
436    /* Get the local parameters of the LLCP Link */
437    status = phFriNfc_Llcp_GetLocalInfo(pLlcpTransport->pLlcp,&LlcpLinkParamInfo);
438    if(status != NFCSTATUS_SUCCESS)
439    {
440       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
441    }
442    else
443    {
444       /* Search a socket free in the Socket Table*/
445       do
446       {
447          if(pLlcpTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketDefault)
448          {
449             /* Set the socket pointer to socket of the table */
450             *pLlcpSocket = &pLlcpTransport->pSocketTable[index];
451 
452             /* Store the socket info in the socket pointer */
453             pLlcpTransport->pSocketTable[index].eSocket_Type     = eType;
454             pLlcpTransport->pSocketTable[index].pSocketErrCb     = pErr_Cb;
455 
456             /* Store the context of the upper layer */
457             pLlcpTransport->pSocketTable[index].pContext   = pContext;
458 
459             /* Set the pointers to the different working buffers */
460             if(pLlcpTransport->pSocketTable[index].eSocket_Type != phFriNfc_LlcpTransport_eConnectionLess)
461             {
462                /* Test the socket options */
463                if((psOptions->rw > PHFRINFC_LLCP_RW_MAX) && (eType == phFriNfc_LlcpTransport_eConnectionOriented))
464                {
465                   status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
466                }
467                /* Set socket options */
468                memcpy(&pLlcpTransport->pSocketTable[index].sSocketOption, psOptions, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));
469 
470                /* Set socket local params (MIUX & RW) */
471                pLlcpTransport->pSocketTable[index].localMIUX = (pLlcpTransport->pSocketTable[index].sSocketOption.miu - PHFRINFC_LLCP_MIU_DEFAULT) & PHFRINFC_LLCP_TLV_MIUX_MASK;
472                pLlcpTransport->pSocketTable[index].localRW   = pLlcpTransport->pSocketTable[index].sSocketOption.rw & PHFRINFC_LLCP_TLV_RW_MASK;
473 
474                /* Set the Max length for the Send and Receive Window Buffer */
475                pLlcpTransport->pSocketTable[index].bufferSendMaxLength   = pLlcpTransport->pSocketTable[index].sSocketOption.miu;
476                pLlcpTransport->pSocketTable[index].bufferRwMaxLength     = pLlcpTransport->pSocketTable[index].sSocketOption.miu * ((pLlcpTransport->pSocketTable[index].sSocketOption.rw & PHFRINFC_LLCP_TLV_RW_MASK));
477                pLlcpTransport->pSocketTable[index].bufferLinearLength    = psWorkingBuffer->length - pLlcpTransport->pSocketTable[index].bufferSendMaxLength - pLlcpTransport->pSocketTable[index].bufferRwMaxLength;
478 
479                /* Test the connection oriented buffers length */
480                if((pLlcpTransport->pSocketTable[index].bufferSendMaxLength + pLlcpTransport->pSocketTable[index].bufferRwMaxLength) > psWorkingBuffer->length
481                    || ((pLlcpTransport->pSocketTable[index].bufferLinearLength < PHFRINFC_LLCP_MIU_DEFAULT) && (pLlcpTransport->pSocketTable[index].bufferLinearLength != 0)))
482                {
483                   status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_BUFFER_TOO_SMALL);
484                   return status;
485                }
486 
487                /* Set the pointer and the length for the Receive Window Buffer */
488                for(cpt=0;cpt<pLlcpTransport->pSocketTable[index].localRW;cpt++)
489                {
490                   pLlcpTransport->pSocketTable[index].sSocketRwBufferTable[cpt].buffer = psWorkingBuffer->buffer + (cpt*pLlcpTransport->pSocketTable[index].sSocketOption.miu);
491                   pLlcpTransport->pSocketTable[index].sSocketRwBufferTable[cpt].length = 0;
492                }
493 
494                /* Set the pointer and the length for the Send Buffer */
495                pLlcpTransport->pSocketTable[index].sSocketSendBuffer.buffer     = psWorkingBuffer->buffer + pLlcpTransport->pSocketTable[index].bufferRwMaxLength;
496                pLlcpTransport->pSocketTable[index].sSocketSendBuffer.length     = pLlcpTransport->pSocketTable[index].bufferSendMaxLength;
497 
498                /** Set the pointer and the length for the Linear Buffer */
499                pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.buffer   = psWorkingBuffer->buffer + pLlcpTransport->pSocketTable[index].bufferRwMaxLength + pLlcpTransport->pSocketTable[index].bufferSendMaxLength;
500                pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.length   = pLlcpTransport->pSocketTable[index].bufferLinearLength;
501 
502                if(pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.length != 0)
503                {
504                   /* Init Cyclic Fifo */
505                   phFriNfc_Llcp_CyclicFifoInit(&pLlcpTransport->pSocketTable[index].sCyclicFifoBuffer,
506                                                pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.buffer,
507                                                pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.length);
508                }
509             }
510             /* Store index of the socket */
511             pLlcpTransport->pSocketTable[index].index = index;
512 
513             /* Set the socket into created state */
514             pLlcpTransport->pSocketTable[index].eSocket_State = phFriNfc_LlcpTransportSocket_eSocketCreated;
515             return status;
516          }
517          else
518          {
519             index++;
520          }
521       }while(index<PHFRINFC_LLCP_NB_SOCKET_MAX);
522 
523       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INSUFFICIENT_RESOURCES);
524    }
525    return status;
526 }
527 
528 /**
529 * \ingroup grp_fri_nfc
530 * \brief <b>Close a socket on a LLCP-connected device</b>.
531 *
532 * This function closes a LLCP socket previously created using phFriNfc_LlcpTransport_Socket.
533 * If the socket was connected, it is first disconnected, and then closed.
534 *
535 * \param[in]  pLlcpSocket                    A pointer to a phFriNfc_LlcpTransport_Socket_t.
536 
537 * \retval NFCSTATUS_SUCCESS                  Operation successful.
538 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
539 *                                            could not be properly interpreted.
540 * \retval NFCSTATUS_FAILED                   Operation failed.
541 */
phFriNfc_LlcpTransport_Close(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket)542 NFCSTATUS phFriNfc_LlcpTransport_Close(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket)
543 {
544    NFCSTATUS status = NFCSTATUS_SUCCESS;
545 
546    /* Check for NULL pointers */
547    if( pLlcpSocket == NULL)
548    {
549       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
550    }
551    else if(pLlcpSocket->eSocket_Type == phFriNfc_LlcpTransport_eConnectionOriented)
552    {
553       status = phFriNfc_LlcpTransport_ConnectionOriented_Close(pLlcpSocket);
554    }
555    else if(pLlcpSocket->eSocket_Type ==  phFriNfc_LlcpTransport_eConnectionLess)
556    {
557       status = phFriNfc_LlcpTransport_Connectionless_Close(pLlcpSocket);
558    }
559    else
560    {
561       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
562    }
563 
564    return status;
565 }
566 
567 /**
568 * \ingroup grp_fri_nfc
569 * \brief <b>Bind a socket to a local SAP</b>.
570 *
571 * This function binds the socket to a local Service Access Point.
572 *
573 * \param[out] pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
574 * \param[in]  pConfigInfo           A port number for a specific socket
575 *
576 * \retval NFCSTATUS_SUCCESS                  Operation successful.
577 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
578 *                                            could not be properly interpreted.
579 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
580 *                                            a valid type to perform the requsted operation.
581 * \retval NFCSTATUS_ALREADY_REGISTERED       The selected SAP is already bound to another
582                                              socket.
583 * \retval NFCSTATUS_FAILED                   Operation failed.
584 */
585 
phFriNfc_LlcpTransport_Bind(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket,uint8_t nSap)586 NFCSTATUS phFriNfc_LlcpTransport_Bind(phFriNfc_LlcpTransport_Socket_t    *pLlcpSocket,
587                                       uint8_t                            nSap)
588 {
589    NFCSTATUS status = NFCSTATUS_SUCCESS;
590    uint8_t i;
591 
592    /* Check for NULL pointers */
593    if(pLlcpSocket == NULL)
594    {
595       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
596    }
597    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketCreated)
598    {
599       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
600    }
601    else if(nSap<2 || nSap>63)
602    {
603       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
604    }
605    else
606    {
607       /* Test if the nSap it is useb by another socket */
608       for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++)
609       {
610          if((pLlcpSocket->psTransport->pSocketTable[i].socket_sSap == nSap)
611             && (pLlcpSocket->psTransport->pSocketTable[i].eSocket_Type == pLlcpSocket->eSocket_Type))
612          {
613             return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_ALREADY_REGISTERED);
614          }
615       }
616       /* Set the nSap value of the socket */
617       pLlcpSocket->socket_sSap = nSap;
618       /* Set the socket state */
619       pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketBound;
620    }
621    return status;
622 }
623 
624 /*********************************************/
625 /*           ConnectionOriented              */
626 /*********************************************/
627 
628 /**
629 * \ingroup grp_fri_nfc
630 * \brief <b>Listen for incoming connection requests on a socket</b>.
631 *
632 * This function switches a socket into a listening state and registers a callback on
633 * incoming connection requests. In this state, the socket is not able to communicate
634 * directly. The listening state is only available for connection-oriented sockets
635 * which are still not connected. The socket keeps listening until it is closed, and
636 * thus can trigger several times the pListen_Cb callback.
637 *
638 *
639 * \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
640 * \param[in]  psServiceName      A pointer to Service Name
641 * \param[in]  pListen_Cb         The callback to be called each time the
642 *                                socket receive a connection request.
643 * \param[in]  pContext           Upper layer context to be returned in
644 *                                the callback.
645 *
646 * \retval NFCSTATUS_SUCCESS                  Operation successful.
647 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
648 *                                            could not be properly interpreted.
649 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state to switch
650 *                                            to listening state.
651 * \retval NFCSTATUS_FAILED                   Operation failed.
652 */
phFriNfc_LlcpTransport_Listen(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket,phNfc_sData_t * psServiceName,pphFriNfc_LlcpTransportSocketListenCb_t pListen_Cb,void * pContext)653 NFCSTATUS phFriNfc_LlcpTransport_Listen(phFriNfc_LlcpTransport_Socket_t*          pLlcpSocket,
654                                         phNfc_sData_t                             *psServiceName,
655                                         pphFriNfc_LlcpTransportSocketListenCb_t   pListen_Cb,
656                                         void*                                     pContext)
657 {
658    NFCSTATUS status = NFCSTATUS_SUCCESS;
659 
660    /* Check for NULL pointers */
661    if(pLlcpSocket == NULL || pListen_Cb == NULL|| pContext == NULL || psServiceName == NULL)
662    {
663       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
664    }
665    /* Check for socket state */
666    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
667    {
668       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
669    }
670    /* Check for socket type */
671    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
672    {
673       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
674    }
675    /* Test if a listen is not pending with this socket */
676    else if(pLlcpSocket->bSocketListenPending)
677    {
678       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
679    }
680    /* Test the length of the SN */
681    else if(psServiceName->length > PHFRINFC_LLCP_SN_MAX_LENGTH)
682    {
683       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
684    }
685    /* Test the SAP range for SDP-advertised services */
686    else if((psServiceName->length > 0) &&
687            (!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_SDP_ADVERTISED_FIRST, PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST)) &&
688            (!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_WKS_FIRST, PHFRINFC_LLCP_SAP_SDP_ADVERTISED_FIRST)))
689    {
690       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
691    }
692    /* Test the SAP range for non SDP-advertised services */
693    else if((psServiceName->length == 0) &&
694            (!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST, PHFRINFC_LLCP_SAP_NUMBER)) &&
695            (!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_WKS_FIRST, PHFRINFC_LLCP_SAP_SDP_ADVERTISED_FIRST)))
696    {
697       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
698    }
699    else
700    {
701       status = phFriNfc_LlcpTransport_ConnectionOriented_Listen(pLlcpSocket,
702                                                                 psServiceName,
703                                                                 pListen_Cb,
704                                                                 pContext);
705    }
706    return status;
707 }
708 
709 /**
710 * \ingroup grp_fri_nfc
711 * \brief <b>Accept an incoming connection request for a socket</b>.
712 *
713 * This functions allows the client to accept an incoming connection request.
714 * It must be used with the socket provided within the listen callback. The socket
715 * is implicitly switched to the connected state when the function is called.
716 *
717 * \param[in]  pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
718 * \param[in]  psOptions             The options to be used with the socket.
719 * \param[in]  psWorkingBuffer       A working buffer to be used by the library.
720 * \param[in]  pErr_Cb               The callback to be called each time the accepted socket
721 *                                   is in error.
722 * \param[in]  pContext              Upper layer context to be returned in the callback.
723 *
724 * \retval NFCSTATUS_SUCCESS                  Operation successful.
725 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
726 *                                            could not be properly interpreted.
727 * \retval NFCSTATUS_BUFFER_TOO_SMALL         The working buffer is too small for the MIU and RW
728 *                                            declared in the options.
729 * \retval NFCSTATUS_FAILED                   Operation failed.
730 */
phFriNfc_LlcpTransport_Accept(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket,phFriNfc_LlcpTransport_sSocketOptions_t * psOptions,phNfc_sData_t * psWorkingBuffer,pphFriNfc_LlcpTransportSocketErrCb_t pErr_Cb,pphFriNfc_LlcpTransportSocketAcceptCb_t pAccept_RspCb,void * pContext)731 NFCSTATUS phFriNfc_LlcpTransport_Accept(phFriNfc_LlcpTransport_Socket_t*             pLlcpSocket,
732                                         phFriNfc_LlcpTransport_sSocketOptions_t*     psOptions,
733                                         phNfc_sData_t*                               psWorkingBuffer,
734                                         pphFriNfc_LlcpTransportSocketErrCb_t         pErr_Cb,
735                                         pphFriNfc_LlcpTransportSocketAcceptCb_t      pAccept_RspCb,
736                                         void*                                        pContext)
737 {
738    NFCSTATUS status = NFCSTATUS_SUCCESS;
739 
740    /* Check for NULL pointers */
741    if(pLlcpSocket == NULL || psOptions == NULL || psWorkingBuffer == NULL || pErr_Cb == NULL || pContext == NULL)
742    {
743       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
744    }
745    /* Check for socket state */
746    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
747    {
748       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
749    }
750    /* Check for socket type */
751    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
752    {
753       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
754    }
755    /* Test the socket options */
756    else if(psOptions->rw > PHFRINFC_LLCP_RW_MAX)
757    {
758       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
759    }
760    else
761    {
762       /* Set the Max length for the Send and Receive Window Buffer */
763       pLlcpSocket->bufferSendMaxLength   = psOptions->miu;
764       pLlcpSocket->bufferRwMaxLength     = psOptions->miu * ((psOptions->rw & PHFRINFC_LLCP_TLV_RW_MASK));
765       pLlcpSocket->bufferLinearLength    = psWorkingBuffer->length - pLlcpSocket->bufferSendMaxLength - pLlcpSocket->bufferRwMaxLength;
766 
767       /* Test the buffers length */
768       if((pLlcpSocket->bufferSendMaxLength + pLlcpSocket->bufferRwMaxLength) > psWorkingBuffer->length
769           || ((pLlcpSocket->bufferLinearLength < PHFRINFC_LLCP_MIU_DEFAULT)  && (pLlcpSocket->bufferLinearLength != 0)))
770       {
771          status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_BUFFER_TOO_SMALL);
772       }
773       else
774       {
775          pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;
776 
777          status  = phFriNfc_LlcpTransport_ConnectionOriented_Accept(pLlcpSocket,
778                                                                     psOptions,
779                                                                     psWorkingBuffer,
780                                                                     pErr_Cb,
781                                                                     pAccept_RspCb,
782                                                                     pContext);
783       }
784    }
785    return status;
786 }
787 
788  /**
789 * \ingroup grp_fri_nfc
790 * \brief <b>Reject an incoming connection request for a socket</b>.
791 *
792 * This functions allows the client to reject an incoming connection request.
793 * It must be used with the socket provided within the listen callback. The socket
794 * is implicitly closed when the function is called.
795 *
796 * \param[in]  pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
797 * \param[in]  pReject_RspCb         The callback to be call when the Reject operation is completed
798 * \param[in]  pContext              Upper layer context to be returned in the callback.
799 *
800 * \retval NFCSTATUS_SUCCESS                  Operation successful.
801 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
802 *                                            could not be properly interpreted.
803 * \retval NFCSTATUS_FAILED                   Operation failed.
804 */
phFriNfc_LlcpTransport_Reject(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket,pphFriNfc_LlcpTransportSocketRejectCb_t pReject_RspCb,void * pContext)805 NFCSTATUS phFriNfc_LlcpTransport_Reject( phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
806                                           pphFriNfc_LlcpTransportSocketRejectCb_t   pReject_RspCb,
807                                           void                                      *pContext)
808 {
809    NFCSTATUS status = NFCSTATUS_SUCCESS;
810 
811    /* Check for NULL pointers */
812    if(pLlcpSocket == NULL)
813    {
814       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
815    }
816    /* Check for socket state */
817    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
818    {
819       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
820    }
821    /* Check for socket type */
822    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
823    {
824       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
825    }
826    else
827    {
828       status = phLibNfc_LlcpTransport_ConnectionOriented_Reject(pLlcpSocket,
829                                                                 pReject_RspCb,
830                                                                 pContext);
831    }
832 
833    return status;
834 }
835 
836 /**
837 * \ingroup grp_fri_nfc
838 * \brief <b>Try to establish connection with a socket on a remote SAP</b>.
839 *
840 * This function tries to connect to a given SAP on the remote peer. If the
841 * socket is not bound to a local SAP, it is implicitly bound to a free SAP.
842 *
843 * \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
844 * \param[in]  nSap               The destination SAP to connect to.
845 * \param[in]  pConnect_RspCb     The callback to be called when the connection
846 *                                operation is completed.
847 * \param[in]  pContext           Upper layer context to be returned in
848 *                                the callback.
849 *
850 * \retval NFCSTATUS_SUCCESS                  Operation successful.
851 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
852 *                                            could not be properly interpreted.
853 * \retval NFCSTATUS_PENDING                  Connection operation is in progress,
854 *                                            pConnect_RspCb will be called upon completion.
855 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
856 *                                            a valid type to perform the requsted operation.
857 * \retval NFCSTATUS_FAILED                   Operation failed.
858 */
phFriNfc_LlcpTransport_Connect(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket,uint8_t nSap,pphFriNfc_LlcpTransportSocketConnectCb_t pConnect_RspCb,void * pContext)859 NFCSTATUS phFriNfc_LlcpTransport_Connect( phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
860                                           uint8_t                                    nSap,
861                                           pphFriNfc_LlcpTransportSocketConnectCb_t   pConnect_RspCb,
862                                           void*                                      pContext)
863 {
864    NFCSTATUS status = NFCSTATUS_SUCCESS;
865    uint8_t i;
866 
867    /* Check for NULL pointers */
868    if(pLlcpSocket == NULL || pConnect_RspCb == NULL || pContext == NULL)
869    {
870       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
871    }
872    /* Test the port number value */
873    else if(nSap<02 || nSap>63)
874    {
875       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
876    }
877    /* Test if the socket is a connectionOriented socket */
878    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
879    {
880       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
881    }
882 
883    /* Test if the socket is not in connecting or connected state*/
884    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketCreated && pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
885    {
886       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
887    }
888    else
889    {
890       /* Implicit bind if socket is not already bound */
891       if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
892       {
893          status = phFriNfc_LlcpTransport_AutoBind(pLlcpSocket);
894          if (status != NFCSTATUS_SUCCESS)
895          {
896             return status;
897          }
898       }
899 
900       /* Test the SAP range for non SDP-advertised services */
901       if(!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST, PHFRINFC_LLCP_SAP_NUMBER))
902       {
903          status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
904       }
905       else
906       {
907          status = phFriNfc_LlcpTransport_ConnectionOriented_Connect(pLlcpSocket,
908                                                                     nSap,
909                                                                     NULL,
910                                                                     pConnect_RspCb,
911                                                                     pContext);
912       }
913    }
914 
915    return status;
916 }
917 
918 /**
919 * \ingroup grp_fri_nfc
920 * \brief <b>Try to establish connection with a socket on a remote service, given its URI</b>.
921 *
922 * This function tries to connect to a SAP designated by an URI. If the
923 * socket is not bound to a local SAP, it is implicitly bound to a free SAP.
924 *
925 * \param[in]  pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
926 * \param[in]  psUri              The URI corresponding to the destination SAP to connect to.
927 * \param[in]  pConnect_RspCb     The callback to be called when the connection
928 *                                operation is completed.
929 * \param[in]  pContext           Upper layer context to be returned in
930 *                                the callback.
931 *
932 * \retval NFCSTATUS_SUCCESS                  Operation successful.
933 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
934 *                                            could not be properly interpreted.
935 * \retval NFCSTATUS_PENDING                  Connection operation is in progress,
936 *                                            pConnect_RspCb will be called upon completion.
937 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
938 *                                            a valid type to perform the requsted operation.
939 * \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
940 * \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
941 * \retval NFCSTATUS_FAILED                   Operation failed.
942 */
phFriNfc_LlcpTransport_ConnectByUri(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket,phNfc_sData_t * psUri,pphFriNfc_LlcpTransportSocketConnectCb_t pConnect_RspCb,void * pContext)943 NFCSTATUS phFriNfc_LlcpTransport_ConnectByUri(phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
944                                               phNfc_sData_t*                             psUri,
945                                               pphFriNfc_LlcpTransportSocketConnectCb_t   pConnect_RspCb,
946                                               void*                                      pContext)
947 {
948    NFCSTATUS status = NFCSTATUS_SUCCESS;
949    uint8_t i;
950 
951    /* Check for NULL pointers */
952    if(pLlcpSocket == NULL || pConnect_RspCb == NULL || pContext == NULL)
953    {
954       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
955    }
956    /* Test if the socket is a connectionOriented socket */
957    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
958    {
959       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
960    }
961    /* Test if the socket is not in connect pending or connected state*/
962    else if(pLlcpSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnecting || pLlcpSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected)
963    {
964       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
965    }
966    /* Test the length of the SN */
967    else if(psUri->length > PHFRINFC_LLCP_SN_MAX_LENGTH)
968    {
969       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
970    }
971    else
972    {
973       /* Implicit bind if socket is not already bound */
974       if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
975       {
976          status = phFriNfc_LlcpTransport_AutoBind(pLlcpSocket);
977          if (status != NFCSTATUS_SUCCESS)
978          {
979             return status;
980          }
981       }
982 
983       /* Test the SAP range for non SDP-advertised services */
984       if(!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST, PHFRINFC_LLCP_SAP_NUMBER))
985       {
986          status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
987       }
988       else
989       {
990          status = phFriNfc_LlcpTransport_ConnectionOriented_Connect(pLlcpSocket,
991                                                                     PHFRINFC_LLCP_SAP_DEFAULT,
992                                                                     psUri,
993                                                                     pConnect_RspCb,
994                                                                     pContext);
995       }
996    }
997 
998    return status;
999 }
1000 
1001 /**
1002 * \ingroup grp_lib_nfc
1003 * \brief <b>Disconnect a currently connected socket</b>.
1004 *
1005 * This function initiates the disconnection of a previously connected socket.
1006 *
1007 * \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
1008 * \param[in]  pDisconnect_RspCb  The callback to be called when the
1009 *                                operation is completed.
1010 * \param[in]  pContext           Upper layer context to be returned in
1011 *                                the callback.
1012 *
1013 * \retval NFCSTATUS_SUCCESS                  Operation successful.
1014 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
1015 *                                            could not be properly interpreted.
1016 * \retval NFCSTATUS_PENDING                  Disconnection operation is in progress,
1017 *                                            pDisconnect_RspCb will be called upon completion.
1018 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
1019 *                                            a valid type to perform the requsted operation.
1020 * \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
1021 * \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
1022 * \retval NFCSTATUS_FAILED                   Operation failed.
1023 */
phFriNfc_LlcpTransport_Disconnect(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket,pphLibNfc_LlcpSocketDisconnectCb_t pDisconnect_RspCb,void * pContext)1024 NFCSTATUS phFriNfc_LlcpTransport_Disconnect(phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
1025                                             pphLibNfc_LlcpSocketDisconnectCb_t         pDisconnect_RspCb,
1026                                             void*                                      pContext)
1027 {
1028    NFCSTATUS status = NFCSTATUS_SUCCESS;
1029 
1030    /* Check for NULL pointers */
1031    if(pLlcpSocket == NULL || pDisconnect_RspCb == NULL || pContext == NULL)
1032    {
1033       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
1034    }
1035    /* Test if the socket is a connectionOriented socket */
1036    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
1037    {
1038       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
1039    }
1040    /* Test if the socket is connected  state*/
1041    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketConnected)
1042    {
1043        status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
1044    }
1045    else
1046    {
1047       status = phLibNfc_LlcpTransport_ConnectionOriented_Disconnect(pLlcpSocket,
1048                                                                     pDisconnect_RspCb,
1049                                                                     pContext);
1050    }
1051 
1052    return status;
1053 }
1054 
1055 /**
1056 * \ingroup grp_fri_nfc
1057 * \brief <b>Send data on a socket</b>.
1058 *
1059 * This function is used to write data on a socket. This function
1060 * can only be called on a connection-oriented socket which is already
1061 * in a connected state.
1062 *
1063 *
1064 * \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
1065 * \param[in]  psBuffer           The buffer containing the data to send.
1066 * \param[in]  pSend_RspCb        The callback to be called when the
1067 *                                operation is completed.
1068 * \param[in]  pContext           Upper layer context to be returned in
1069 *                                the callback.
1070 *
1071 * \retval NFCSTATUS_SUCCESS                  Operation successful.
1072 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
1073 *                                            could not be properly interpreted.
1074 * \retval NFCSTATUS_PENDING                  Reception operation is in progress,
1075 *                                            pSend_RspCb will be called upon completion.
1076 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
1077 *                                            a valid type to perform the requsted operation.
1078 * \retval NFCSTATUS_FAILED                   Operation failed.
1079 */
phFriNfc_LlcpTransport_Send(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket,phNfc_sData_t * psBuffer,pphFriNfc_LlcpTransportSocketSendCb_t pSend_RspCb,void * pContext)1080 NFCSTATUS phFriNfc_LlcpTransport_Send(phFriNfc_LlcpTransport_Socket_t*             pLlcpSocket,
1081                                       phNfc_sData_t*                               psBuffer,
1082                                       pphFriNfc_LlcpTransportSocketSendCb_t        pSend_RspCb,
1083                                       void*                                        pContext)
1084 {
1085    NFCSTATUS status = NFCSTATUS_SUCCESS;
1086 
1087    /* Check for NULL pointers */
1088    if(pLlcpSocket == NULL || psBuffer == NULL || pSend_RspCb == NULL || pContext == NULL)
1089    {
1090       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
1091    }
1092    /* Test if the socket is a connectionOriented socket */
1093    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
1094    {
1095       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
1096    }
1097    /* Test if the socket is in connected state */
1098    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketConnected)
1099    {
1100       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
1101    }
1102    /* Test the length of the buffer */
1103    else if(psBuffer->length > pLlcpSocket->remoteMIU )
1104    {
1105       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
1106    }
1107    /* Test if a send is pending */
1108    else if(pLlcpSocket->pfSocketSend_Cb != NULL)
1109    {
1110       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_REJECTED);
1111    }
1112    else
1113    {
1114       status = phFriNfc_LlcpTransport_ConnectionOriented_Send(pLlcpSocket,
1115                                                               psBuffer,
1116                                                               pSend_RspCb,
1117                                                               pContext);
1118    }
1119 
1120    return status;
1121 }
1122 
1123  /**
1124 * \ingroup grp_fri_nfc
1125 * \brief <b>Read data on a socket</b>.
1126 *
1127 * This function is used to read data from a socket. It reads at most the
1128 * size of the reception buffer, but can also return less bytes if less bytes
1129 * are available. If no data is available, the function will be pending until
1130 * more data comes, and the response will be sent by the callback. This function
1131 * can only be called on a connection-oriented socket.
1132 *
1133 *
1134 * \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
1135 * \param[in]  psBuffer           The buffer receiving the data.
1136 * \param[in]  pRecv_RspCb        The callback to be called when the
1137 *                                operation is completed.
1138 * \param[in]  pContext           Upper layer context to be returned in
1139 *                                the callback.
1140 *
1141 * \retval NFCSTATUS_SUCCESS                  Operation successful.
1142 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
1143 *                                            could not be properly interpreted.
1144 * \retval NFCSTATUS_PENDING                  Reception operation is in progress,
1145 *                                            pRecv_RspCb will be called upon completion.
1146 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
1147 *                                            a valid type to perform the requsted operation.
1148 * \retval NFCSTATUS_FAILED                   Operation failed.
1149 */
phFriNfc_LlcpTransport_Recv(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket,phNfc_sData_t * psBuffer,pphFriNfc_LlcpTransportSocketRecvCb_t pRecv_RspCb,void * pContext)1150 NFCSTATUS phFriNfc_LlcpTransport_Recv( phFriNfc_LlcpTransport_Socket_t*             pLlcpSocket,
1151                                        phNfc_sData_t*                               psBuffer,
1152                                        pphFriNfc_LlcpTransportSocketRecvCb_t        pRecv_RspCb,
1153                                        void*                                        pContext)
1154 {
1155    NFCSTATUS status = NFCSTATUS_SUCCESS;
1156 
1157    /* Check for NULL pointers */
1158    if(pLlcpSocket == NULL || psBuffer == NULL || pRecv_RspCb == NULL || pContext == NULL)
1159    {
1160       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
1161    }
1162    /* Test if the socket is a connectionOriented socket */
1163    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
1164    {
1165       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
1166    }
1167    /* Test if the socket is in connected state */
1168    else if(pLlcpSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketDefault)
1169    {
1170       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
1171    }
1172    /* Test if a receive is pending */
1173    else if(pLlcpSocket->bSocketRecvPending == TRUE)
1174    {
1175       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_REJECTED);
1176    }
1177    else
1178    {
1179       status = phFriNfc_LlcpTransport_ConnectionOriented_Recv(pLlcpSocket,
1180                                                               psBuffer,
1181                                                               pRecv_RspCb,
1182                                                               pContext);
1183    }
1184 
1185    return status;
1186 }
1187 
1188 /*****************************************/
1189 /*           ConnectionLess              */
1190 /*****************************************/
1191 
1192 /**
1193 * \ingroup grp_fri_nfc
1194 * \brief <b>Send data on a socket to a given destination SAP</b>.
1195 *
1196 * This function is used to write data on a socket to a given destination SAP.
1197 * This function can only be called on a connectionless socket.
1198 *
1199 *
1200 * \param[in]  pLlcpSocket        A pointer to a LlcpSocket created.
1201 * \param[in]  nSap               The destination SAP.
1202 * \param[in]  psBuffer           The buffer containing the data to send.
1203 * \param[in]  pSend_RspCb        The callback to be called when the
1204 *                                operation is completed.
1205 * \param[in]  pContext           Upper layer context to be returned in
1206 *                                the callback.
1207 *
1208 * \retval NFCSTATUS_SUCCESS                  Operation successful.
1209 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
1210 *                                            could not be properly interpreted.
1211 * \retval NFCSTATUS_PENDING                  Reception operation is in progress,
1212 *                                            pSend_RspCb will be called upon completion.
1213 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
1214 *                                            a valid type to perform the requsted operation.
1215 * \retval NFCSTATUS_FAILED                   Operation failed.
1216 */
phFriNfc_LlcpTransport_SendTo(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket,uint8_t nSap,phNfc_sData_t * psBuffer,pphFriNfc_LlcpTransportSocketSendCb_t pSend_RspCb,void * pContext)1217 NFCSTATUS phFriNfc_LlcpTransport_SendTo( phFriNfc_LlcpTransport_Socket_t             *pLlcpSocket,
1218                                          uint8_t                                     nSap,
1219                                          phNfc_sData_t                               *psBuffer,
1220                                          pphFriNfc_LlcpTransportSocketSendCb_t       pSend_RspCb,
1221                                          void*                                       pContext)
1222 {
1223    NFCSTATUS status = NFCSTATUS_SUCCESS;
1224    phFriNfc_Llcp_sLinkParameters_t  LlcpRemoteLinkParamInfo;
1225 
1226    if(pLlcpSocket == NULL || psBuffer == NULL || pSend_RspCb == NULL || pContext == NULL)
1227    {
1228       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
1229    }
1230    /* Test the port number value */
1231    else if(nSap<2 || nSap>63)
1232    {
1233       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
1234    }
1235    /* Test if the socket is a connectionless socket */
1236    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionLess)
1237    {
1238        status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
1239    }
1240    /* Test if the socket is in an updated state */
1241    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
1242    {
1243       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
1244    }
1245    else
1246    {
1247       /* Get the local parameters of the LLCP Link */
1248       status = phFriNfc_Llcp_GetRemoteInfo(pLlcpSocket->psTransport->pLlcp,&LlcpRemoteLinkParamInfo);
1249       if(status != NFCSTATUS_SUCCESS)
1250       {
1251          status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
1252       }
1253       /* Test the length of the socket buffer for ConnectionLess mode*/
1254       else if(psBuffer->length > LlcpRemoteLinkParamInfo.miu)
1255       {
1256          status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
1257       }
1258       /* Test if the link is in error state */
1259       else if(pLlcpSocket->psTransport->LinkStatusError)
1260       {
1261          status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_REJECTED);
1262       }
1263       else
1264       {
1265          status = phFriNfc_LlcpTransport_Connectionless_SendTo(pLlcpSocket,
1266                                                                nSap,
1267                                                                psBuffer,
1268                                                                pSend_RspCb,
1269                                                                pContext);
1270       }
1271    }
1272 
1273    return status;
1274 }
1275 
1276 
1277  /**
1278 * \ingroup grp_lib_nfc
1279 * \brief <b>Read data on a socket and get the source SAP</b>.
1280 *
1281 * This function is the same as phLibNfc_Llcp_Recv, except that the callback includes
1282 * the source SAP. This functions can only be called on a connectionless socket.
1283 *
1284 *
1285 * \param[in]  pLlcpSocket        A pointer to a LlcpSocket created.
1286 * \param[in]  psBuffer           The buffer receiving the data.
1287 * \param[in]  pRecv_RspCb        The callback to be called when the
1288 *                                operation is completed.
1289 * \param[in]  pContext           Upper layer context to be returned in
1290 *                                the callback.
1291 *
1292 * \retval NFCSTATUS_SUCCESS                  Operation successful.
1293 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
1294 *                                            could not be properly interpreted.
1295 * \retval NFCSTATUS_PENDING                  Reception operation is in progress,
1296 *                                            pRecv_RspCb will be called upon completion.
1297 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
1298 *                                            a valid type to perform the requsted operation.
1299 * \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
1300 * \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
1301 * \retval NFCSTATUS_FAILED                   Operation failed.
1302 */
phFriNfc_LlcpTransport_RecvFrom(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket,phNfc_sData_t * psBuffer,pphFriNfc_LlcpTransportSocketRecvFromCb_t pRecv_Cb,void * pContext)1303 NFCSTATUS phFriNfc_LlcpTransport_RecvFrom( phFriNfc_LlcpTransport_Socket_t                   *pLlcpSocket,
1304                                            phNfc_sData_t*                                    psBuffer,
1305                                            pphFriNfc_LlcpTransportSocketRecvFromCb_t         pRecv_Cb,
1306                                            void*                                             pContext)
1307 {
1308    NFCSTATUS status = NFCSTATUS_SUCCESS;
1309    if(pLlcpSocket == NULL || psBuffer == NULL || pRecv_Cb == NULL || pContext == NULL)
1310    {
1311       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
1312    }
1313    /* Test if the socket is a connectionless socket */
1314    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionLess)
1315    {
1316       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
1317    }
1318    /* Test if the socket is in an updated state */
1319    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
1320    {
1321       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
1322    }
1323    else
1324    {
1325       if(pLlcpSocket->bSocketRecvPending)
1326       {
1327          status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_REJECTED);
1328       }
1329       else
1330       {
1331          status = phLibNfc_LlcpTransport_Connectionless_RecvFrom(pLlcpSocket,
1332                                                                  psBuffer,
1333                                                                  pRecv_Cb,
1334                                                                  pContext);
1335       }
1336    }
1337 
1338    return status;
1339 }
1340