phFriNfc_LlcpMacNfcip.c revision c2c730a21faacadbb607bfa182795262d00a8ec7
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/**
19 * \file  phFriNfc_LlcpMacNfcip.c
20 * \brief NFC LLCP MAC Mappings For Different RF Technologies.
21 *
22 * Project: NFC-FRI
23 *
24 */
25
26
27/*include files*/
28#include <phFriNfc_LlcpMac.h>
29#include <phLibNfcStatus.h>
30#include <phLibNfc.h>
31#include <phLibNfc_Internal.h>
32#include <stdio.h>
33#include <string.h>
34
35static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t               *LlcpMac,
36                                             phNfc_sData_t                    *psData,
37                                             phFriNfc_LlcpMac_Send_CB_t       LlcpMacSend_Cb,
38                                             void                             *pContext);
39
40
41static void phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(phFriNfc_LlcpMac_t  *LlcpMac,
42                                                 NFCSTATUS           status)
43{
44   phFriNfc_LlcpMac_Reveive_CB_t pfReceiveCB;
45   void                          *pReceiveContext;
46
47   if (LlcpMac->MacReceive_Cb != NULL)
48   {
49      /* Save callback params */
50      pfReceiveCB = LlcpMac->MacReceive_Cb;
51      pReceiveContext = LlcpMac->MacReceive_Context;
52
53      /* Reset the pointer to the Receive Callback and Context*/
54      LlcpMac->MacReceive_Cb = NULL;
55      LlcpMac->MacReceive_Context = NULL;
56
57      /* Call the receive callback */
58      pfReceiveCB(pReceiveContext, status, LlcpMac->psReceiveBuffer);
59   }
60}
61
62static void phFriNfc_LlcpMac_Nfcip_TriggerSendCb(phFriNfc_LlcpMac_t  *LlcpMac,
63                                                 NFCSTATUS           status)
64{
65   phFriNfc_LlcpMac_Send_CB_t pfSendCB;
66   void                       *pSendContext;
67
68   if (LlcpMac->MacSend_Cb != NULL)
69   {
70      /* Save context in local variables */
71      pfSendCB     = LlcpMac->MacSend_Cb;
72      pSendContext = LlcpMac->MacSend_Context;
73
74      /* Reset the pointer to the Send Callback */
75      LlcpMac->MacSend_Cb = NULL;
76      LlcpMac->MacSend_Context = NULL;
77
78      /* Call Send callback */
79      pfSendCB(pSendContext, status);
80   }
81}
82
83static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Chk(phFriNfc_LlcpMac_t                   *LlcpMac,
84                                            phFriNfc_LlcpMac_Chk_CB_t            ChkLlcpMac_Cb,
85                                            void                                 *pContext)
86{
87   NFCSTATUS status = NFCSTATUS_SUCCESS;
88   uint8_t Llcp_Magic_Number[] = {0x46,0x66,0x6D};
89
90   if(NULL == LlcpMac || NULL == ChkLlcpMac_Cb || NULL == pContext)
91   {
92      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
93   }
94   else
95   {
96      status = (NFCSTATUS)memcmp(Llcp_Magic_Number,LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo,3);
97      if(!status)
98      {
99         LlcpMac->sConfigParam.buffer = &LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo[3] ;
100         LlcpMac->sConfigParam.length = (LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length - 3);
101         status = NFCSTATUS_SUCCESS;
102      }
103      else
104      {
105         status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED);
106      }
107   }
108
109   ChkLlcpMac_Cb(pContext,status);
110   return status;
111}
112
113static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Activate (phFriNfc_LlcpMac_t   *LlcpMac)
114{
115   NFCSTATUS status  = NFCSTATUS_SUCCESS;
116
117   if(LlcpMac == NULL)
118   {
119      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
120   }
121   else
122   {
123      LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkActivated;
124      LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context,
125                             LlcpMac->LinkState,
126                             &LlcpMac->sConfigParam,
127                             LlcpMac->PeerRemoteDevType);
128   }
129
130   return status;
131}
132
133static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Deactivate (phFriNfc_LlcpMac_t   *LlcpMac)
134{
135   NFCSTATUS status  = NFCSTATUS_SUCCESS;
136
137   if(NULL == LlcpMac)
138   {
139      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
140   }
141   else
142   {
143      /* Set the flag of LinkStatus to deactivate */
144      LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkDeactivated;
145   }
146
147   if (LlcpMac->SendPending)
148   {
149      /* Reset Flag */
150      LlcpMac->SendPending = FALSE;
151
152      phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, NFCSTATUS_FAILED);
153   }
154
155   if (LlcpMac->RecvPending)
156   {
157      /* Reset Flag */
158      LlcpMac->RecvPending = FALSE;
159
160      phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, NFCSTATUS_FAILED);
161   }
162
163   LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context,
164                          LlcpMac->LinkState,
165                          NULL,
166                          LlcpMac->PeerRemoteDevType);
167
168   return status;
169}
170
171static void phFriNfc_LlcpMac_Nfcip_Send_Cb(void       *pContext,
172                                           NFCSTATUS   Status)
173{
174   phFriNfc_LlcpMac_t            *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
175
176#ifdef LLCP_CHANGES
177   if(gpphLibContext->LibNfcState.next_state
178                               == eLibNfcHalStateShutdown)
179   {
180      phLibNfc_Pending_Shutdown();
181      Status = NFCSTATUS_SHUTDOWN;
182   }
183#endif /* #ifdef LLCP_CHANGES */
184
185   /* Reset Send and Receive Flag */
186   LlcpMac->SendPending = FALSE;
187   LlcpMac->RecvPending = FALSE;
188
189   phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status);
190
191}
192
193static void phFriNfc_LlcpMac_Nfcip_Receive_Cb(void       *pContext,
194                                              NFCSTATUS   Status)
195{
196   phFriNfc_LlcpMac_t               *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
197#ifdef LLCP_CHANGES
198
199   phFriNfc_LlcpMac_Send_CB_t       pfSendCB;
200   void                             *pSendContext;
201
202
203   if(gpphLibContext->LibNfcState.next_state
204                               == eLibNfcHalStateShutdown)
205   {
206      phLibNfc_Pending_Shutdown();
207      Status = NFCSTATUS_SHUTDOWN;
208   }
209
210   if (NFCSTATUS_SHUTDOWN == Status)
211   {
212      /* Save context in local variables */
213      pfSendCB = LlcpMac->MacSend_Cb;
214      pSendContext = LlcpMac->MacSend_Context;
215
216      /* Reset the pointer to the Send Callback */
217      LlcpMac->MacSend_Cb = NULL;
218      LlcpMac->MacSend_Context = NULL;
219
220      /* Reset Send and Receive Flag */
221      LlcpMac->SendPending = FALSE;
222      LlcpMac->RecvPending = FALSE;
223   }
224
225#endif /* #ifdef LLCP_CHANGES */
226
227   phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status);
228
229#ifdef LLCP_CHANGES
230
231   if (NFCSTATUS_SHUTDOWN == Status)
232   {
233       if ((LlcpMac->SendPending) && (NULL != pfSendCB))
234       {
235           pfSendCB(pSendContext, Status);
236      }
237   }
238   else
239
240#endif /* #ifdef LLCP_CHANGES */
241   {
242   /* Test if a send is pending */
243   if(LlcpMac->SendPending)
244   {
245      Status = phFriNfc_LlcpMac_Nfcip_Send(LlcpMac,LlcpMac->psSendBuffer,LlcpMac->MacSend_Cb,LlcpMac->MacReceive_Context);
246   }
247}
248}
249
250static void phFriNfc_LlcpMac_Nfcip_Transceive_Cb(void       *pContext,
251                                                 NFCSTATUS   Status)
252{
253   phFriNfc_LlcpMac_t               *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
254
255#ifdef LLCP_CHANGES
256   if(gpphLibContext->LibNfcState.next_state
257                               == eLibNfcHalStateShutdown)
258   {
259      phLibNfc_Pending_Shutdown();
260      Status = NFCSTATUS_SHUTDOWN;
261   }
262#endif /* #ifdef LLCP_CHANGES */
263
264   /* Reset Send and Receive Flag */
265   LlcpMac->SendPending = FALSE;
266   LlcpMac->RecvPending = FALSE;
267
268   /* Call the callbacks */
269   phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status);
270   phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status);
271}
272
273static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t               *LlcpMac,
274                                             phNfc_sData_t                    *psData,
275                                             phFriNfc_LlcpMac_Send_CB_t       LlcpMacSend_Cb,
276                                             void                             *pContext)
277{
278   NFCSTATUS status = NFCSTATUS_SUCCESS;
279
280   if(NULL == LlcpMac || NULL == psData || NULL == LlcpMacSend_Cb || NULL == pContext)
281   {
282      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
283   }
284   else if(LlcpMac->MacSend_Cb != NULL && LlcpMac->PeerRemoteDevType == phFriNfc_LlcpMac_ePeerTypeInitiator)
285   {
286      /*Previous callback is pending */
287      status = NFCSTATUS_REJECTED;
288   }
289   else
290   {
291      /* Save the LlcpMacSend_Cb */
292      LlcpMac->MacSend_Cb = LlcpMacSend_Cb;
293      LlcpMac->MacSend_Context = pContext;
294
295      switch(LlcpMac->PeerRemoteDevType)
296      {
297      case phFriNfc_LlcpMac_ePeerTypeInitiator:
298         {
299            if(LlcpMac->RecvPending)
300            {
301               /*set the completion routines for the LLCP Transceive function*/
302                LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb;
303                LlcpMac->MacCompletionInfo.Context = LlcpMac;
304
305                /* set the command type*/
306                LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw;
307
308                /* set the Additional Info*/
309                LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
310                LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0;
311                LlcpMac->SendPending = TRUE;
312
313                status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice,
314                                                    &LlcpMac->MacCompletionInfo,
315                                                    LlcpMac->psRemoteDevInfo,
316                                                    LlcpMac->Cmd,
317                                                    &LlcpMac->psDepAdditionalInfo,
318                                                    psData->buffer,
319                                                    (uint16_t)psData->length,
320                                                    LlcpMac->psReceiveBuffer->buffer,
321                                                    (uint16_t*)&LlcpMac->psReceiveBuffer->length);
322            }
323            else
324            {
325               LlcpMac->SendPending = TRUE;
326               LlcpMac->psSendBuffer = psData;
327               return status = NFCSTATUS_PENDING;
328            }
329         }break;
330      case phFriNfc_LlcpMac_ePeerTypeTarget:
331         {
332            if(!LlcpMac->RecvPending)
333            {
334               LlcpMac->SendPending = TRUE;
335               LlcpMac->psSendBuffer = psData;
336               return status = NFCSTATUS_PENDING;
337            }
338            else
339            {
340               /*set the completion routines for the LLCP Send function*/
341               LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Send_Cb;
342               LlcpMac->MacCompletionInfo.Context = LlcpMac;
343               status = phFriNfc_OvrHal_Send(LlcpMac->LowerDevice,
344                                             &LlcpMac->MacCompletionInfo,
345                                             LlcpMac->psRemoteDevInfo,
346                                             psData->buffer,
347                                             (uint16_t)psData->length);
348            }
349         }break;
350      default:
351         {
352            status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE);
353         }break;
354      }
355   }
356   return status;
357}
358
359static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Receive(phFriNfc_LlcpMac_t               *LlcpMac,
360                                                phNfc_sData_t                    *psData,
361                                                phFriNfc_LlcpMac_Reveive_CB_t    LlcpMacReceive_Cb,
362                                                void                             *pContext)
363{
364   NFCSTATUS status = NFCSTATUS_SUCCESS;
365   if(NULL == LlcpMac || NULL==psData || NULL == LlcpMacReceive_Cb || NULL == pContext)
366   {
367      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
368   }
369   else if(LlcpMac->MacReceive_Cb != NULL)
370   {
371      /*Previous callback is pending */
372      status = NFCSTATUS_REJECTED;
373   }
374   else
375   {
376      /* Save the LlcpMacReceive_Cb */
377      LlcpMac->MacReceive_Cb = LlcpMacReceive_Cb;
378      LlcpMac->MacReceive_Context = pContext;
379
380      /* Save the pointer to the receive buffer */
381      LlcpMac->psReceiveBuffer= psData;
382
383      switch(LlcpMac->PeerRemoteDevType)
384      {
385      case phFriNfc_LlcpMac_ePeerTypeInitiator:
386         {
387            if(LlcpMac->SendPending)
388            {
389               /*set the completion routines for the LLCP Transceive function*/
390               LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb;
391               LlcpMac->MacCompletionInfo.Context = LlcpMac;
392               /* set the command type*/
393               LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw;
394               /* set the Additional Info*/
395               LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
396               LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0;
397               LlcpMac->RecvPending = TRUE;
398
399               status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice,
400                                                   &LlcpMac->MacCompletionInfo,
401                                                   LlcpMac->psRemoteDevInfo,
402                                                   LlcpMac->Cmd,
403                                                   &LlcpMac->psDepAdditionalInfo,
404                                                   LlcpMac->psSendBuffer->buffer,
405                                                   (uint16_t)LlcpMac->psSendBuffer->length,
406                                                   psData->buffer,
407                                                   (uint16_t*)&psData->length);
408            }
409            else
410            {
411               LlcpMac->RecvPending = TRUE;
412               return status = NFCSTATUS_PENDING;
413            }
414         }break;
415      case phFriNfc_LlcpMac_ePeerTypeTarget:
416         {
417             /*set the completion routines for the LLCP Receive function*/
418            LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Receive_Cb;
419            /* save the context of LlcpMacNfcip */
420            LlcpMac->MacCompletionInfo.Context = LlcpMac;
421            LlcpMac->RecvPending = TRUE;
422
423            status = phFriNfc_OvrHal_Receive(LlcpMac->LowerDevice,
424                                             &LlcpMac->MacCompletionInfo,
425                                             LlcpMac->psRemoteDevInfo,
426                                             LlcpMac->psReceiveBuffer->buffer,
427                                             (uint16_t*)&LlcpMac->psReceiveBuffer->length);
428         }break;
429      default:
430         {
431            status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE);
432         }break;
433      }
434   }
435   return status;
436}
437
438
439NFCSTATUS phFriNfc_LlcpMac_Nfcip_Register (phFriNfc_LlcpMac_t *LlcpMac)
440{
441   NFCSTATUS status = NFCSTATUS_SUCCESS;
442
443   if(NULL != LlcpMac)
444   {
445      LlcpMac->LlcpMacInterface.chk = phFriNfc_LlcpMac_Nfcip_Chk;
446      LlcpMac->LlcpMacInterface.activate   = phFriNfc_LlcpMac_Nfcip_Activate;
447      LlcpMac->LlcpMacInterface.deactivate = phFriNfc_LlcpMac_Nfcip_Deactivate;
448      LlcpMac->LlcpMacInterface.send = phFriNfc_LlcpMac_Nfcip_Send;
449      LlcpMac->LlcpMacInterface.receive = phFriNfc_LlcpMac_Nfcip_Receive;
450
451      return NFCSTATUS_SUCCESS;
452   }
453   else
454   {
455      return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED);
456   }
457}
458