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#include <phNfcTypes.h>
18#include <phLibNfc.h>
19#include <phLibNfc_Internal.h>
20#include <phFriNfc_Llcp.h>
21#include <phFriNfc_LlcpTransport.h>
22
23/* ---------------------------- Internal macros -------------------------------- */
24
25#ifndef STATIC_DISABLE
26#define STATIC static
27#else
28#define STATIC
29#endif
30
31/* ----------------------- Internal functions headers -------------------------- */
32
33STATIC
34NFCSTATUS static_CheckState();
35
36STATIC
37NFCSTATUS static_CheckDevice(phLibNfc_Handle hRemoteDevice);
38
39STATIC
40void phLibNfc_Llcp_CheckLlcp_Cb(void *pContext,NFCSTATUS status);
41
42STATIC
43void phLibNfc_Llcp_Link_Cb(void *pContext,phLibNfc_Llcp_eLinkStatus_t status);
44
45/* --------------------------- Internal functions ------------------------------ */
46
47STATIC NFCSTATUS static_CheckState()
48{
49   /* Check if the global context is set */
50   if(gpphLibContext == NULL)
51   {
52      return NFCSTATUS_NOT_INITIALISED;
53   }
54
55   /* Check if initialized */
56   if(gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown)
57   {
58      return NFCSTATUS_NOT_INITIALISED;
59   }
60
61   /* Check if shutting down */
62   if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown)
63   {
64      return NFCSTATUS_SHUTDOWN;
65   }
66
67   return NFCSTATUS_SUCCESS;
68}
69
70STATIC NFCSTATUS static_CheckDevice(phLibNfc_Handle hRemoteDevice)
71{
72   phLibNfc_sRemoteDevInformation_t*   psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice;
73
74   if (hRemoteDevice == NULL)
75   {
76      return NFCSTATUS_INVALID_PARAMETER;
77   }
78
79   /* If local device is the Initiator (remote is Target),
80    * check if connection is correct
81    */
82   if (psRemoteDevInfo->RemDevType == phHal_eNfcIP1_Target)
83   {
84      /* Check if any device connected */
85      if(gpphLibContext->Connected_handle == 0)
86      {
87         return NFCSTATUS_TARGET_NOT_CONNECTED;
88      }
89
90      /* Check if handle corresponds to connected one */
91      if(hRemoteDevice != gpphLibContext->Connected_handle)
92      {
93         return NFCSTATUS_INVALID_HANDLE;
94      }
95   }
96
97   /* Check if previous callback is pending or if remote peer is not LLCP compliant */
98   if ((gpphLibContext->status.GenCb_pending_status == TRUE) ||
99            (gpphLibContext->llcp_cntx.bIsLlcp == FALSE))
100   {
101      return NFCSTATUS_REJECTED;
102   }
103
104   return NFCSTATUS_SUCCESS;
105}
106
107/* ---------------------------- Public functions ------------------------------- */
108
109NFCSTATUS phLibNfc_Mgt_SetLlcp_ConfigParams( phLibNfc_Llcp_sLinkParameters_t* pConfigInfo,
110                                            pphLibNfc_RspCb_t                pConfigRspCb,
111                                            void*                            pContext
112                                            )
113{
114   NFCSTATUS      result;
115   phNfc_sData_t  sGeneralBytesBuffer;
116   phLibNfc_sNfcIPCfg_t sNfcIPCfg;
117   const uint8_t  pMagicBuffer[] = { 0x46, 0x66, 0x6D };
118
119   /* State checking */
120   result = static_CheckState();
121   if (result != NFCSTATUS_SUCCESS)
122   {
123      return result;
124   }
125
126   /* Parameters checking */
127   if ((pConfigInfo == NULL) || (pConfigRspCb == NULL))
128   {
129      return NFCSTATUS_INVALID_PARAMETER;
130   }
131
132   /* Save the config for later use */
133   memcpy( &gpphLibContext->llcp_cntx.sLocalParams,
134           pConfigInfo,
135           sizeof(phLibNfc_Llcp_sLinkParameters_t) );
136
137   /* Copy magic number in NFCIP General Bytes */
138   memcpy(sNfcIPCfg.generalBytes, pMagicBuffer, sizeof(pMagicBuffer));
139   sNfcIPCfg.generalBytesLength = sizeof(pMagicBuffer);
140
141   /* Encode link parameters in TLV to configure P2P General Bytes */
142   sGeneralBytesBuffer.buffer = sNfcIPCfg.generalBytes + sizeof(pMagicBuffer);
143   sGeneralBytesBuffer.length = sizeof(sNfcIPCfg.generalBytes) - sizeof(pMagicBuffer);
144   result = phFriNfc_Llcp_EncodeLinkParams( &sGeneralBytesBuffer,
145                                            pConfigInfo,
146                                            PHFRINFC_LLCP_VERSION);
147   if (result != NFCSTATUS_SUCCESS)
148   {
149      return PHNFCSTATUS(result);
150   }
151   sNfcIPCfg.generalBytesLength += (uint8_t)sGeneralBytesBuffer.length;
152
153   /* Set the P2P general bytes */
154   result = phLibNfc_Mgt_SetP2P_ConfigParams(&sNfcIPCfg, pConfigRspCb, pContext);
155   if (result != NFCSTATUS_PENDING)
156   {
157      return PHNFCSTATUS(result);
158   }
159
160   /* Resets the LLCP LLC component */
161   result = phFriNfc_Llcp_Reset( &gpphLibContext->llcp_cntx.sLlcpContext,
162                                 gpphLibContext->psOverHalCtxt,
163                                 pConfigInfo,
164                                 gpphLibContext->llcp_cntx.pRxBuffer,
165                                 sizeof(gpphLibContext->llcp_cntx.pRxBuffer),
166                                 gpphLibContext->llcp_cntx.pTxBuffer,
167                                 sizeof(gpphLibContext->llcp_cntx.pTxBuffer),
168                                 phLibNfc_Llcp_Link_Cb,
169                                 gpphLibContext);
170   if (result != NFCSTATUS_SUCCESS)
171   {
172      return PHNFCSTATUS(result);
173   }
174
175   /* Resets the LLCP Transport component */
176   result = phFriNfc_LlcpTransport_Reset( &gpphLibContext->llcp_cntx.sLlcpTransportContext,
177                                          &gpphLibContext->llcp_cntx.sLlcpContext );
178   if (result != NFCSTATUS_SUCCESS)
179   {
180      return PHNFCSTATUS(result);
181   }
182
183   return NFCSTATUS_PENDING;
184}
185
186NFCSTATUS phLibNfc_Llcp_CheckLlcp( phLibNfc_Handle              hRemoteDevice,
187                                   pphLibNfc_ChkLlcpRspCb_t     pCheckLlcp_RspCb,
188                                   pphLibNfc_LlcpLinkStatusCb_t pLink_Cb,
189                                   void*                        pContext
190                                   )
191{
192   NFCSTATUS                           result;
193   phLibNfc_sRemoteDevInformation_t*   psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice;
194
195   /* State checking */
196   result = static_CheckState();
197   if (result != NFCSTATUS_SUCCESS)
198   {
199      return result;
200   }
201
202   /* Parameters checking */
203   if ((hRemoteDevice == 0)       ||
204       (pCheckLlcp_RspCb == NULL) ||
205       (pLink_Cb == NULL))
206   {
207      return NFCSTATUS_INVALID_PARAMETER;
208   }
209
210   /* If local device is the Initiator (remote is Target),
211    * check if connection is correct
212    */
213   if (psRemoteDevInfo->RemDevType == phHal_eNfcIP1_Target)
214   {
215      /* Check if any device connected */
216      if(gpphLibContext->Connected_handle == 0)
217      {
218         return NFCSTATUS_TARGET_NOT_CONNECTED;
219      }
220
221      /* Check if handle corresponds to connected one */
222      if(hRemoteDevice != gpphLibContext->Connected_handle)
223      {
224         return NFCSTATUS_INVALID_HANDLE;
225      }
226   }
227
228   /* Prepare callback */
229   gpphLibContext->CBInfo.pClientLlcpLinkCb = pLink_Cb;
230   gpphLibContext->CBInfo.pClientLlcpLinkCntx = pContext;
231
232   // DEBUG: Reset at least the state
233   gpphLibContext->llcp_cntx.sLlcpContext.state = 0;
234
235   /* Prepare callback */
236   gpphLibContext->CBInfo.pClientLlcpCheckRespCb = pCheckLlcp_RspCb;
237   gpphLibContext->CBInfo.pClientLlcpCheckRespCntx = pContext;
238
239   /* Update state */
240   result = phLibNfc_UpdateNextState(gpphLibContext, eLibNfcHalStateTransaction);
241   if (result != NFCSTATUS_SUCCESS)
242   {
243      return result;
244   }
245
246   /* Call the component function */
247   result = phFriNfc_Llcp_ChkLlcp( &gpphLibContext->llcp_cntx.sLlcpContext,
248                                   psRemoteDevInfo,
249                                   phLibNfc_Llcp_CheckLlcp_Cb,
250                                   gpphLibContext
251                                   );
252   result = PHNFCSTATUS(result);
253   if (result == NFCSTATUS_PENDING)
254   {
255      gpphLibContext->status.GenCb_pending_status = TRUE;
256   }
257   else if (result == NFCSTATUS_SUCCESS)
258   {
259      /* Nothing to do */
260   }
261   else if (result != NFCSTATUS_FAILED)
262   {
263      result = NFCSTATUS_TARGET_LOST;
264   }
265
266   return result;
267}
268
269/* LLCP link callback */
270STATIC
271void phLibNfc_Llcp_Link_Cb(void *pContext, phLibNfc_Llcp_eLinkStatus_t status)
272{
273   phLibNfc_LibContext_t         *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)pContext;
274   pphLibNfc_LlcpLinkStatusCb_t  pClientCb = NULL;
275   void                          *pClientContext = NULL;
276
277   if(pLibNfc_Ctxt != gpphLibContext)
278   {
279      /*wrong context returned from below layer*/
280      phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
281   }
282   else
283   {
284      /* Close all sockets */
285      phFriNfc_LlcpTransport_CloseAll(&gpphLibContext->llcp_cntx.sLlcpTransportContext);
286
287      /* Copy callback details */
288      pClientCb = gpphLibContext->CBInfo.pClientLlcpLinkCb;
289      pClientContext = gpphLibContext->CBInfo.pClientLlcpLinkCntx;
290
291      /* Trigger the callback */
292      if(pClientCb != NULL)
293      {
294         pClientCb(pClientContext, status);
295      }
296   }
297}
298
299/* Response callback for phLibNfc_Ndef_CheckNdef */
300STATIC
301void phLibNfc_Llcp_CheckLlcp_Cb(void *pContext, NFCSTATUS status)
302{
303   phLibNfc_LibContext_t      *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)pContext;
304   NFCSTATUS                  RetStatus = NFCSTATUS_SUCCESS;
305   pphLibNfc_ChkLlcpRspCb_t   pClientCb = NULL;
306   void                       *pClientContext = NULL;
307
308   if(pLibNfc_Ctxt != gpphLibContext)
309   {
310      /*wrong context returned from below layer*/
311      phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
312   }
313   else
314   {
315      if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown)
316      {
317         /*shutdown called before completion of check Ndef, allow shutdown to happen */
318         phLibNfc_Pending_Shutdown();
319         RetStatus = NFCSTATUS_SHUTDOWN;
320      }
321      else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateRelease)
322      {
323         RetStatus = NFCSTATUS_ABORTED;
324      }
325      else
326      {
327         if(status == NFCSTATUS_SUCCESS)
328         {
329            /* Remote peer is LLCP compliant */
330            gpphLibContext->llcp_cntx.bIsLlcp = TRUE;
331         }
332         else if(PHNFCSTATUS(status)== NFCSTATUS_FAILED)
333         {
334            RetStatus = NFCSTATUS_FAILED;
335            gpphLibContext->llcp_cntx.bIsLlcp = FALSE;
336         }
337         else
338         {
339            RetStatus = NFCSTATUS_TARGET_LOST;
340         }
341      }
342
343      /* Update the current state */
344      gpphLibContext->status.GenCb_pending_status = FALSE;
345      phLibNfc_UpdateCurState(RetStatus,gpphLibContext);
346
347      /* Copy callback details */
348      pClientCb = gpphLibContext->CBInfo.pClientLlcpCheckRespCb;
349      pClientContext = gpphLibContext->CBInfo.pClientLlcpCheckRespCntx;
350
351      /* Reset saved callback */
352      gpphLibContext->CBInfo.pClientCkNdefCb = NULL;
353      gpphLibContext->CBInfo.pClientCkNdefCntx = NULL;
354
355      /* Trigger the callback */
356      if(pClientCb != NULL)
357      {
358         pClientCb(pClientContext,RetStatus);
359      }
360   }
361}
362
363NFCSTATUS phLibNfc_Llcp_Activate( phLibNfc_Handle hRemoteDevice )
364{
365   NFCSTATUS result;
366
367   /* State checking */
368   result = static_CheckState();
369   if (result != NFCSTATUS_SUCCESS)
370   {
371      return result;
372   }
373
374   /* Parameters checking */
375   if (hRemoteDevice == 0)
376   {
377      return NFCSTATUS_INVALID_PARAMETER;
378   }
379
380   /* Check device */
381   result = static_CheckDevice(hRemoteDevice);
382   if (result != NFCSTATUS_SUCCESS)
383   {
384      return result;
385   }
386
387   /* Start activation */
388   result = phFriNfc_Llcp_Activate(&gpphLibContext->llcp_cntx.sLlcpContext);
389
390   return PHNFCSTATUS(result);
391}
392
393NFCSTATUS phLibNfc_Llcp_Deactivate( phLibNfc_Handle  hRemoteDevice )
394{
395   NFCSTATUS result;
396
397   /* State checking */
398   result = static_CheckState();
399   if (result != NFCSTATUS_SUCCESS)
400   {
401      return result;
402   }
403
404   /* Parameters checking */
405   if (hRemoteDevice == 0)
406   {
407      return NFCSTATUS_INVALID_PARAMETER;
408   }
409
410   /* Check device */
411   result = static_CheckDevice(hRemoteDevice);
412   if (result != NFCSTATUS_SUCCESS)
413   {
414      return result;
415   }
416
417   /* Start deactivation */
418   result = phFriNfc_Llcp_Deactivate(&gpphLibContext->llcp_cntx.sLlcpContext);
419
420   return PHNFCSTATUS(result);
421}
422
423NFCSTATUS phLibNfc_Llcp_GetLocalInfo( phLibNfc_Handle                  hRemoteDevice,
424                                      phLibNfc_Llcp_sLinkParameters_t* pConfigInfo
425                                      )
426{
427   NFCSTATUS result;
428
429   /* State checking */
430   result = static_CheckState();
431   if (result != NFCSTATUS_SUCCESS)
432   {
433      return result;
434   }
435
436   /* Parameters checking */
437   if (pConfigInfo == NULL)
438   {
439      return NFCSTATUS_INVALID_PARAMETER;
440   }
441
442   /* Get local infos */
443   result = phFriNfc_Llcp_GetLocalInfo(&gpphLibContext->llcp_cntx.sLlcpContext, pConfigInfo);
444
445   return PHNFCSTATUS(result);
446}
447
448NFCSTATUS phLibNfc_Llcp_GetRemoteInfo( phLibNfc_Handle                    hRemoteDevice,
449                                       phLibNfc_Llcp_sLinkParameters_t*   pConfigInfo
450                                       )
451{
452   NFCSTATUS result;
453
454   /* State checking */
455   result = static_CheckState();
456   if (result != NFCSTATUS_SUCCESS)
457   {
458      return result;
459   }
460
461   /* Parameters checking */
462   if ((hRemoteDevice == 0) ||
463       (pConfigInfo == NULL))
464   {
465      return NFCSTATUS_INVALID_PARAMETER;
466   }
467
468   /* Check device */
469   result = static_CheckDevice(hRemoteDevice);
470   if (result != NFCSTATUS_SUCCESS)
471   {
472      return result;
473   }
474
475   /* Get local infos */
476   result = phFriNfc_Llcp_GetRemoteInfo(&gpphLibContext->llcp_cntx.sLlcpContext, pConfigInfo);
477
478   return PHNFCSTATUS(result);
479}
480
481NFCSTATUS phLibNfc_Llcp_DiscoverServices( phLibNfc_Handle     hRemoteDevice,
482                                          phNfc_sData_t       *psServiceNameList,
483                                          uint8_t             *pnSapList,
484                                          uint8_t             nListSize,
485                                          pphLibNfc_RspCb_t   pDiscover_Cb,
486                                          void                *pContext
487                                          )
488{
489   NFCSTATUS                           result;
490   PHNFC_UNUSED_VARIABLE(hRemoteDevice);
491
492   /* State checking */
493   result = static_CheckState();
494   if (result != NFCSTATUS_SUCCESS)
495   {
496      return result;
497   }
498
499   /* Parameters checking */
500   if ((hRemoteDevice == 0)       ||
501       (psServiceNameList == NULL) ||
502       (pnSapList == NULL) ||
503       (nListSize == 0) ||
504       (pDiscover_Cb == NULL))
505   {
506      return NFCSTATUS_INVALID_PARAMETER;
507   }
508
509   /* Check device */
510   result = static_CheckDevice(hRemoteDevice);
511   if (result != NFCSTATUS_SUCCESS)
512   {
513      return result;
514   }
515
516   /* Prepare callback */
517   gpphLibContext->CBInfo.pClientLlcpDiscoveryCb = pDiscover_Cb;
518   gpphLibContext->CBInfo.pClientLlcpDiscoveryCntx = pContext;
519
520   /* Update state */
521   result = phLibNfc_UpdateNextState(gpphLibContext, eLibNfcHalStateTransaction);
522   if (result != NFCSTATUS_SUCCESS)
523   {
524      return result;
525   }
526
527   /* Call the component function */
528   result = phFriNfc_LlcpTransport_DiscoverServices( &gpphLibContext->llcp_cntx.sLlcpTransportContext,
529                                                     psServiceNameList,
530                                                     pnSapList,
531                                                     nListSize,
532                                                     pDiscover_Cb,
533                                                     pContext
534                                                     );
535   result = PHNFCSTATUS(result);
536   if ((result == NFCSTATUS_PENDING) || (result == NFCSTATUS_SUCCESS))
537   {
538      /* Nothing to do */
539   }
540   else if (result != NFCSTATUS_FAILED)
541   {
542      result = NFCSTATUS_TARGET_LOST;
543   }
544
545   return result;
546}
547
548NFCSTATUS phLibNfc_Llcp_Socket( phLibNfc_Llcp_eSocketType_t      eType,
549                                phLibNfc_Llcp_sSocketOptions_t*  psOptions,
550                                phNfc_sData_t*                   psWorkingBuffer,
551                                phLibNfc_Handle*                 phSocket,
552                                pphLibNfc_LlcpSocketErrCb_t      pErr_Cb,
553                                void*                            pContext
554                                )
555{
556   NFCSTATUS                        result;
557   phFriNfc_LlcpTransport_Socket_t  *psSocket;
558
559   /* State checking */
560   result = static_CheckState();
561   if (result != NFCSTATUS_SUCCESS)
562   {
563      return result;
564   }
565
566   /* Parameters checking */
567   /* NOTE: Transport Layer test psOption and psWorkingBuffer value */
568   if ((phSocket == NULL)        ||
569       (pErr_Cb == NULL))
570   {
571      return NFCSTATUS_INVALID_PARAMETER;
572   }
573
574   /* Get local infos */
575   result = phFriNfc_LlcpTransport_Socket(&gpphLibContext->llcp_cntx.sLlcpTransportContext,
576                                          eType,
577                                          psOptions,
578                                          psWorkingBuffer,
579                                          &psSocket,
580                                          pErr_Cb,
581                                          pContext);
582
583   /* Send back the socket handle */
584   *phSocket = (phLibNfc_Handle)psSocket;
585
586   return PHNFCSTATUS(result);
587}
588
589NFCSTATUS phLibNfc_Llcp_Close( phLibNfc_Handle hSocket )
590{
591   NFCSTATUS                        result;
592   phFriNfc_LlcpTransport_Socket_t  *psSocket = (phFriNfc_LlcpTransport_Socket_t*)hSocket;
593
594   /* State checking */
595   result = static_CheckState();
596   if (result != NFCSTATUS_SUCCESS)
597   {
598      return result;
599   }
600
601   /* Parameters checking */
602   if (hSocket == 0)
603   {
604      return NFCSTATUS_INVALID_PARAMETER;
605   }
606
607   /* Get local infos */
608   /* TODO: if connected abort and close else close only */
609   result = phFriNfc_LlcpTransport_Close(psSocket);
610
611   return PHNFCSTATUS(result);
612}
613
614NFCSTATUS phLibNfc_Llcp_SocketGetLocalOptions( phLibNfc_Handle                  hSocket,
615                                               phLibNfc_Llcp_sSocketOptions_t*  psLocalOptions
616                                               )
617{
618   NFCSTATUS                        result;
619   phFriNfc_LlcpTransport_Socket_t  *psSocket = (phFriNfc_LlcpTransport_Socket_t*)hSocket;
620
621   /* State checking */
622   result = static_CheckState();
623   if (result != NFCSTATUS_SUCCESS)
624   {
625      return result;
626   }
627
628   /* Parameters checking */
629   if ((hSocket == 0) ||
630       (psLocalOptions == NULL))
631   {
632      return NFCSTATUS_INVALID_PARAMETER;
633   }
634
635   /* Get local options */
636   result = phFriNfc_LlcpTransport_SocketGetLocalOptions(psSocket, psLocalOptions);
637
638   return PHNFCSTATUS(result);
639}
640
641NFCSTATUS phLibNfc_Llcp_SocketGetRemoteOptions( phLibNfc_Handle                  hRemoteDevice,
642                                                phLibNfc_Handle                  hSocket,
643                                                phLibNfc_Llcp_sSocketOptions_t*  psRemoteOptions
644                                                )
645{
646   NFCSTATUS                        result;
647   phFriNfc_LlcpTransport_Socket_t  *psSocket = (phFriNfc_LlcpTransport_Socket_t*)hSocket;
648
649   LLCP_PRINT("phLibNfc_Llcp_SocketGetRemoteOptions");
650
651   /* State checking */
652   result = static_CheckState();
653   if (result != NFCSTATUS_SUCCESS)
654   {
655      return result;
656   }
657
658   /* Parameters checking */
659   if ((hRemoteDevice == 0) ||
660       (hSocket == 0)       ||
661       (psRemoteOptions == NULL))
662   {
663      return NFCSTATUS_INVALID_PARAMETER;
664   }
665
666   /* Check device */
667   result = static_CheckDevice(hRemoteDevice);
668   if (result != NFCSTATUS_SUCCESS)
669   {
670      return result;
671   }
672
673   /* Get remote infos */
674   result = phFriNfc_LlcpTransport_SocketGetRemoteOptions(psSocket, psRemoteOptions);
675
676   return PHNFCSTATUS(result);
677}
678
679NFCSTATUS phLibNfc_Llcp_Bind( phLibNfc_Handle hSocket,
680                              uint8_t         nSap,
681                              phNfc_sData_t * psServiceName
682                              )
683{
684   NFCSTATUS                        result;
685   phFriNfc_LlcpTransport_Socket_t  *psSocket = (phFriNfc_LlcpTransport_Socket_t*)hSocket;
686
687   LLCP_PRINT("phLibNfc_Llcp_Bind");
688
689   /* State checking */
690   result = static_CheckState();
691   if (result != NFCSTATUS_SUCCESS)
692   {
693      return result;
694   }
695
696   /* Parameters checking */
697   if (hSocket == 0)
698   {
699      return NFCSTATUS_INVALID_PARAMETER;
700   }
701
702   /* Bind the socket to the designated port */
703   result = phFriNfc_LlcpTransport_Bind(psSocket, nSap, psServiceName);
704
705   return PHNFCSTATUS(result);
706}
707
708NFCSTATUS phLibNfc_Llcp_Listen( phLibNfc_Handle                  hSocket,
709                                pphLibNfc_LlcpSocketListenCb_t   pListen_Cb,
710                                void*                            pContext
711                                )
712{
713   NFCSTATUS                        result;
714   phFriNfc_LlcpTransport_Socket_t  *psSocket = (phFriNfc_LlcpTransport_Socket_t*)hSocket;
715
716   LLCP_PRINT("phLibNfc_Llcp_Listen");
717
718   /* State checking */
719   result = static_CheckState();
720   if (result != NFCSTATUS_SUCCESS)
721   {
722      return result;
723   }
724
725   /* Parameters checking */
726   /* NOTE : psServiceName may be NULL, do not test it ! */
727   if ((hSocket == 0) ||
728       (pListen_Cb == NULL))
729   {
730      return NFCSTATUS_INVALID_PARAMETER;
731   }
732
733   /* Start listening for incoming connections */
734   result = phFriNfc_LlcpTransport_Listen( psSocket,
735                                           (pphFriNfc_LlcpTransportSocketListenCb_t)pListen_Cb,
736                                           pContext );
737
738   return PHNFCSTATUS(result);
739}
740
741NFCSTATUS phLibNfc_Llcp_Accept( phLibNfc_Handle                  hSocket,
742                                phLibNfc_Llcp_sSocketOptions_t*  psOptions,
743                                phNfc_sData_t*                   psWorkingBuffer,
744                                pphLibNfc_LlcpSocketErrCb_t      pErr_Cb,
745                                pphLibNfc_LlcpSocketAcceptCb_t   pAccept_RspCb,
746                                void*                            pContext
747                                )
748{
749   NFCSTATUS                        result;
750   phFriNfc_LlcpTransport_Socket_t  *psSocket = (phFriNfc_LlcpTransport_Socket_t*)hSocket;
751
752   LLCP_PRINT("phLibNfc_Llcp_Accept");
753
754   /* State checking */
755   result = static_CheckState();
756   if (result != NFCSTATUS_SUCCESS)
757   {
758      return result;
759   }
760
761   /* Parameters checking */
762   if ((hSocket == 0)            ||
763       (psOptions == NULL)       ||
764       (psWorkingBuffer == NULL) ||
765       (pErr_Cb == NULL)         ||
766       (pAccept_RspCb == NULL))
767   {
768      return NFCSTATUS_INVALID_PARAMETER;
769   }
770
771   /* Accept incoming connection */
772   result = phFriNfc_LlcpTransport_Accept( psSocket,
773                                           psOptions,
774                                           psWorkingBuffer,
775                                           pErr_Cb,
776                                           pAccept_RspCb,
777                                           pContext );
778
779   return PHNFCSTATUS(result);
780}
781
782NFCSTATUS phLibNfc_Llcp_Reject( phLibNfc_Handle                  hRemoteDevice,
783                                phLibNfc_Handle                  hSocket,
784                                pphLibNfc_LlcpSocketRejectCb_t   pReject_RspCb,
785                                void*                            pContext
786                                )
787{
788   NFCSTATUS                        result;
789   phFriNfc_LlcpTransport_Socket_t  *psSocket = (phFriNfc_LlcpTransport_Socket_t*)hSocket;
790
791   LLCP_PRINT("phLibNfc_Llcp_Reject");
792
793   /* State checking */
794   result = static_CheckState();
795   if (result != NFCSTATUS_SUCCESS)
796   {
797      return result;
798   }
799
800   /* Parameters checking */
801   if ((hRemoteDevice == 0)      ||
802       (hSocket == 0)            ||
803       (pReject_RspCb == NULL))
804   {
805      return NFCSTATUS_INVALID_PARAMETER;
806   }
807
808   /* Check device */
809   result = static_CheckDevice(hRemoteDevice);
810   if (result != NFCSTATUS_SUCCESS)
811   {
812      return result;
813   }
814
815   /* Reject incoming connection */
816   result = phFriNfc_LlcpTransport_Reject( psSocket,
817                                           pReject_RspCb,
818                                           pContext );
819
820   return PHNFCSTATUS(result);
821}
822
823NFCSTATUS phLibNfc_Llcp_Connect( phLibNfc_Handle                 hRemoteDevice,
824                                 phLibNfc_Handle                 hSocket,
825                                 uint8_t                         nSap,
826                                 pphLibNfc_LlcpSocketConnectCb_t pConnect_RspCb,
827                                 void*                           pContext
828                                 )
829{
830   NFCSTATUS                        result;
831   phFriNfc_LlcpTransport_Socket_t  *psSocket = (phFriNfc_LlcpTransport_Socket_t*)hSocket;
832
833   LLCP_PRINT("phLibNfc_Llcp_Connect");
834
835   /* State checking */
836   result = static_CheckState();
837   if (result != NFCSTATUS_SUCCESS)
838   {
839      return result;
840   }
841
842   /* Parameters checking */
843   if ((hRemoteDevice == 0)      ||
844	   (hSocket == 0)            ||
845       (pConnect_RspCb == NULL))
846   {
847      LLCP_PRINT("phLibNfc_Llcp_Connect NFCSTATUS_INVALID_PARAMETER");
848      return NFCSTATUS_INVALID_PARAMETER;
849   }
850
851   /* Check device */
852   result = static_CheckDevice(hRemoteDevice);
853   if (result != NFCSTATUS_SUCCESS)
854   {
855      return result;
856   }
857
858   /* Try to connect on a remote service, given its SAP */
859   result = phFriNfc_LlcpTransport_Connect( psSocket,
860                                            nSap,
861                                            pConnect_RspCb,
862                                            pContext );
863
864   return PHNFCSTATUS(result);
865}
866
867NFCSTATUS phLibNfc_Llcp_ConnectByUri( phLibNfc_Handle                 hRemoteDevice,
868                                      phLibNfc_Handle                 hSocket,
869                                      phNfc_sData_t*                  psUri,
870                                      pphLibNfc_LlcpSocketConnectCb_t pConnect_RspCb,
871                                      void*                           pContext
872                                      )
873{
874   NFCSTATUS                        result;
875   phFriNfc_LlcpTransport_Socket_t  *psSocket = (phFriNfc_LlcpTransport_Socket_t*)hSocket;
876
877   LLCP_PRINT("phLibNfc_Llcp_ConnectByUri");
878
879   /* State checking */
880   result = static_CheckState();
881   if (result != NFCSTATUS_SUCCESS)
882   {
883      return result;
884   }
885
886   /* Parameters checking */
887   if ((hRemoteDevice == 0)      ||
888       (hSocket == 0)            ||
889       (psUri   == NULL)         ||
890       (pConnect_RspCb == NULL))
891   {
892      LLCP_PRINT("phLibNfc_Llcp_ConnectByUri NFCSTATUS_INVALID_PARAMETER");
893      return NFCSTATUS_INVALID_PARAMETER;
894   }
895
896   /* Check device */
897   result = static_CheckDevice(hRemoteDevice);
898   if (result != NFCSTATUS_SUCCESS)
899   {
900      return result;
901   }
902
903   /* Try to connect on a remote service, using SDP */
904   result = phFriNfc_LlcpTransport_ConnectByUri( psSocket,
905                                                 psUri,
906                                                 pConnect_RspCb,
907                                                 pContext );
908
909   return PHNFCSTATUS(result);
910}
911
912NFCSTATUS phLibNfc_Llcp_Disconnect( phLibNfc_Handle                    hRemoteDevice,
913                                    phLibNfc_Handle                    hSocket,
914                                    pphLibNfc_LlcpSocketDisconnectCb_t pDisconnect_RspCb,
915                                    void*                              pContext
916                                    )
917{
918   NFCSTATUS                        result;
919   phFriNfc_LlcpTransport_Socket_t  *psSocket = (phFriNfc_LlcpTransport_Socket_t*)hSocket;
920
921   LLCP_PRINT("phLibNfc_Llcp_Disconnect");
922
923   /* State checking */
924   result = static_CheckState();
925   if (result != NFCSTATUS_SUCCESS)
926   {
927      return result;
928   }
929
930   /* Parameters checking */
931   if ((hRemoteDevice == 0) ||
932       (hSocket == 0)       ||
933       (pDisconnect_RspCb == NULL))
934   {
935      return NFCSTATUS_INVALID_PARAMETER;
936   }
937
938   /* Check device */
939   result = static_CheckDevice(hRemoteDevice);
940   if (result != NFCSTATUS_SUCCESS)
941   {
942      return result;
943   }
944
945   /* Disconnect a logical link */
946   result = phFriNfc_LlcpTransport_Disconnect( psSocket,
947                                               pDisconnect_RspCb,
948                                               pContext );
949
950   return PHNFCSTATUS(result);
951}
952
953NFCSTATUS phLibNfc_Llcp_Recv( phLibNfc_Handle              hRemoteDevice,
954                              phLibNfc_Handle              hSocket,
955                              phNfc_sData_t*               psBuffer,
956                              pphLibNfc_LlcpSocketRecvCb_t pRecv_RspCb,
957                              void*                        pContext
958                              )
959{
960   NFCSTATUS                        result;
961   phFriNfc_LlcpTransport_Socket_t  *psSocket = (phFriNfc_LlcpTransport_Socket_t*)hSocket;
962
963   LLCP_PRINT("phLibNfc_Llcp_Recv");
964
965   /* State checking */
966   result = static_CheckState();
967   if (result != NFCSTATUS_SUCCESS)
968   {
969      return result;
970   }
971
972   /* Parameters checking */
973   if ((hRemoteDevice == 0)   ||
974       (hSocket == 0)         ||
975       (psBuffer == NULL)     ||
976       (pRecv_RspCb == NULL))
977   {
978      return NFCSTATUS_INVALID_PARAMETER;
979   }
980
981   /* Check device */
982   result = static_CheckDevice(hRemoteDevice);
983   if (result != NFCSTATUS_SUCCESS)
984   {
985      return result;
986   }
987
988   /* Receive data from the logical link */
989   result = phFriNfc_LlcpTransport_Recv( psSocket,
990                                         psBuffer,
991                                         pRecv_RspCb,
992                                         pContext );
993
994   return PHNFCSTATUS(result);
995}
996
997NFCSTATUS phLibNfc_Llcp_RecvFrom( phLibNfc_Handle                   hRemoteDevice,
998                                  phLibNfc_Handle                   hSocket,
999                                  phNfc_sData_t*                    psBuffer,
1000                                  pphLibNfc_LlcpSocketRecvFromCb_t  pRecv_Cb,
1001                                  void*                             pContext
1002                                  )
1003{
1004   NFCSTATUS                        result;
1005   phFriNfc_LlcpTransport_Socket_t  *psSocket = (phFriNfc_LlcpTransport_Socket_t*)hSocket;
1006
1007   LLCP_PRINT("phLibNfc_Llcp_RecvFrom");
1008
1009   /* State checking */
1010   result = static_CheckState();
1011   if (result != NFCSTATUS_SUCCESS)
1012   {
1013      return result;
1014   }
1015
1016   /* Parameters checking */
1017   if ((hRemoteDevice == 0)   ||
1018       (hSocket == 0)         ||
1019       (psBuffer == NULL)     ||
1020       (pRecv_Cb == NULL))
1021   {
1022      return NFCSTATUS_INVALID_PARAMETER;
1023   }
1024
1025   /* Check device */
1026   result = static_CheckDevice(hRemoteDevice);
1027   if (result != NFCSTATUS_SUCCESS)
1028   {
1029      return result;
1030   }
1031
1032   /* Receive data from the logical link */
1033   result = phFriNfc_LlcpTransport_RecvFrom( psSocket,
1034                                             psBuffer,
1035                                             pRecv_Cb,
1036                                             pContext );
1037
1038   return PHNFCSTATUS(result);
1039}
1040
1041NFCSTATUS phLibNfc_Llcp_Send( phLibNfc_Handle              hRemoteDevice,
1042                              phLibNfc_Handle              hSocket,
1043                              phNfc_sData_t*               psBuffer,
1044                              pphLibNfc_LlcpSocketSendCb_t pSend_RspCb,
1045                              void*                        pContext
1046                              )
1047{
1048   NFCSTATUS                        result;
1049   phFriNfc_LlcpTransport_Socket_t  *psSocket = (phFriNfc_LlcpTransport_Socket_t*)hSocket;
1050
1051   LLCP_PRINT("phLibNfc_Llcp_Send");
1052
1053   /* State checking */
1054   result = static_CheckState();
1055   if (result != NFCSTATUS_SUCCESS)
1056   {
1057      return result;
1058   }
1059
1060   /* Parameters checking */
1061   if ((hRemoteDevice == 0)   ||
1062       (hSocket == 0)         ||
1063       (psBuffer == NULL)     ||
1064       (pSend_RspCb == NULL))
1065   {
1066      return NFCSTATUS_INVALID_PARAMETER;
1067   }
1068
1069   /* Check device */
1070   result = static_CheckDevice(hRemoteDevice);
1071   if (result != NFCSTATUS_SUCCESS)
1072   {
1073      return result;
1074   }
1075
1076   /* Send data to the logical link */
1077   result = phFriNfc_LlcpTransport_Send( psSocket,
1078                                         psBuffer,
1079                                         pSend_RspCb,
1080                                         pContext );
1081
1082   return PHNFCSTATUS(result);
1083}
1084
1085NFCSTATUS phLibNfc_Llcp_SendTo( phLibNfc_Handle               hRemoteDevice,
1086                                phLibNfc_Handle               hSocket,
1087                                uint8_t                       nSap,
1088                                phNfc_sData_t*                psBuffer,
1089                                pphLibNfc_LlcpSocketSendCb_t  pSend_RspCb,
1090                                void*                         pContext
1091                                )
1092{
1093   NFCSTATUS                        result;
1094   phFriNfc_LlcpTransport_Socket_t  *psSocket = (phFriNfc_LlcpTransport_Socket_t*)hSocket;
1095
1096   LLCP_PRINT("phLibNfc_Llcp_SendTo");
1097
1098   /* State checking */
1099   result = static_CheckState();
1100   if (result != NFCSTATUS_SUCCESS)
1101   {
1102      return result;
1103   }
1104
1105   /* Parameters checking */
1106   if ((hRemoteDevice == 0)   ||
1107       (hSocket == 0)         ||
1108       (psBuffer == NULL)     ||
1109       (pSend_RspCb == NULL))
1110   {
1111      return NFCSTATUS_INVALID_PARAMETER;
1112   }
1113
1114   /* Check device */
1115   result = static_CheckDevice(hRemoteDevice);
1116   if (result != NFCSTATUS_SUCCESS)
1117   {
1118      return result;
1119   }
1120
1121   /* Send data to the logical link */
1122   result = phFriNfc_LlcpTransport_SendTo( psSocket,
1123                                           nSap,
1124                                           psBuffer,
1125                                           pSend_RspCb,
1126                                           pContext );
1127
1128   return PHNFCSTATUS(result);
1129}
1130