• 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 /**
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 
35 static 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 
phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(phFriNfc_LlcpMac_t * LlcpMac,NFCSTATUS status)41 static 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 
phFriNfc_LlcpMac_Nfcip_TriggerSendCb(phFriNfc_LlcpMac_t * LlcpMac,NFCSTATUS status)62 static 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 
phFriNfc_LlcpMac_Nfcip_Chk(phFriNfc_LlcpMac_t * LlcpMac,phFriNfc_LlcpMac_Chk_CB_t ChkLlcpMac_Cb,void * pContext)83 static 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       ChkLlcpMac_Cb(pContext,status);
108    }
109 
110    return status;
111 }
112 
phFriNfc_LlcpMac_Nfcip_Activate(phFriNfc_LlcpMac_t * LlcpMac)113 static 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 
phFriNfc_LlcpMac_Nfcip_Deactivate(phFriNfc_LlcpMac_t * LlcpMac)133 static 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       if (LlcpMac->SendPending)
147       {
148          /* Reset Flag */
149          LlcpMac->SendPending = FALSE;
150          phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, NFCSTATUS_FAILED);
151       }
152 
153       if (LlcpMac->RecvPending)
154       {
155          /* Reset Flag */
156          LlcpMac->RecvPending = FALSE;
157          phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, NFCSTATUS_FAILED);
158       }
159 
160       LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context,
161                              LlcpMac->LinkState,
162                              NULL,
163                              LlcpMac->PeerRemoteDevType);
164    }
165 
166    return status;
167 }
168 
phFriNfc_LlcpMac_Nfcip_Send_Cb(void * pContext,NFCSTATUS Status)169 static void phFriNfc_LlcpMac_Nfcip_Send_Cb(void       *pContext,
170                                            NFCSTATUS   Status)
171 {
172    phFriNfc_LlcpMac_t            *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
173 
174 #ifdef LLCP_CHANGES
175    if(gpphLibContext->LibNfcState.next_state
176                                == eLibNfcHalStateShutdown)
177    {
178       phLibNfc_Pending_Shutdown();
179       Status = NFCSTATUS_SHUTDOWN;
180    }
181 #endif /* #ifdef LLCP_CHANGES */
182 
183    /* Reset Send and Receive Flag */
184    LlcpMac->SendPending = FALSE;
185    LlcpMac->RecvPending = FALSE;
186 
187    phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status);
188 
189 }
190 
phFriNfc_LlcpMac_Nfcip_Receive_Cb(void * pContext,NFCSTATUS Status)191 static void phFriNfc_LlcpMac_Nfcip_Receive_Cb(void       *pContext,
192                                               NFCSTATUS   Status)
193 {
194    phFriNfc_LlcpMac_t               *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
195 #ifdef LLCP_CHANGES
196 
197    phFriNfc_LlcpMac_Send_CB_t       pfSendCB;
198    void                             *pSendContext;
199 
200 
201    if(gpphLibContext->LibNfcState.next_state
202                                == eLibNfcHalStateShutdown)
203    {
204       phLibNfc_Pending_Shutdown();
205       Status = NFCSTATUS_SHUTDOWN;
206    }
207 
208    if (NFCSTATUS_SHUTDOWN == Status)
209    {
210       /* Save context in local variables */
211       pfSendCB = LlcpMac->MacSend_Cb;
212       pSendContext = LlcpMac->MacSend_Context;
213 
214       /* Reset the pointer to the Send Callback */
215       LlcpMac->MacSend_Cb = NULL;
216       LlcpMac->MacSend_Context = NULL;
217 
218       /* Reset Send and Receive Flag */
219       LlcpMac->SendPending = FALSE;
220       LlcpMac->RecvPending = FALSE;
221    }
222 
223 #endif /* #ifdef LLCP_CHANGES */
224 
225    phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status);
226 
227 #ifdef LLCP_CHANGES
228 
229    if (NFCSTATUS_SHUTDOWN == Status)
230    {
231        if ((LlcpMac->SendPending) && (NULL != pfSendCB))
232        {
233            pfSendCB(pSendContext, Status);
234       }
235    }
236    else
237 
238 #endif /* #ifdef LLCP_CHANGES */
239    {
240    /* Test if a send is pending */
241    if(LlcpMac->SendPending)
242    {
243       Status = phFriNfc_LlcpMac_Nfcip_Send(LlcpMac,LlcpMac->psSendBuffer,LlcpMac->MacSend_Cb,LlcpMac->MacSend_Context);
244    }
245 }
246 }
247 
phFriNfc_LlcpMac_Nfcip_Transceive_Cb(void * pContext,NFCSTATUS Status)248 static void phFriNfc_LlcpMac_Nfcip_Transceive_Cb(void       *pContext,
249                                                  NFCSTATUS   Status)
250 {
251    phFriNfc_LlcpMac_t               *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
252 
253 #ifdef LLCP_CHANGES
254    if(gpphLibContext->LibNfcState.next_state
255                                == eLibNfcHalStateShutdown)
256    {
257       phLibNfc_Pending_Shutdown();
258       Status = NFCSTATUS_SHUTDOWN;
259    }
260 #endif /* #ifdef LLCP_CHANGES */
261 
262    /* Reset Send and Receive Flag */
263    LlcpMac->SendPending = FALSE;
264    LlcpMac->RecvPending = FALSE;
265 
266    /* Call the callbacks */
267    phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status);
268    phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status);
269 }
270 
phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t * LlcpMac,phNfc_sData_t * psData,phFriNfc_LlcpMac_Send_CB_t LlcpMacSend_Cb,void * pContext)271 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t               *LlcpMac,
272                                              phNfc_sData_t                    *psData,
273                                              phFriNfc_LlcpMac_Send_CB_t       LlcpMacSend_Cb,
274                                              void                             *pContext)
275 {
276    NFCSTATUS status = NFCSTATUS_SUCCESS;
277 
278    if(NULL == LlcpMac || NULL == psData || NULL == LlcpMacSend_Cb || NULL == pContext)
279    {
280       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
281    }
282    else if(LlcpMac->MacSend_Cb != NULL && LlcpMac->PeerRemoteDevType == phFriNfc_LlcpMac_ePeerTypeInitiator)
283    {
284       /*Previous callback is pending */
285       status = NFCSTATUS_REJECTED;
286    }
287    else
288    {
289       /* Save the LlcpMacSend_Cb */
290       LlcpMac->MacSend_Cb = LlcpMacSend_Cb;
291       LlcpMac->MacSend_Context = pContext;
292 
293       switch(LlcpMac->PeerRemoteDevType)
294       {
295       case phFriNfc_LlcpMac_ePeerTypeInitiator:
296          {
297             if(LlcpMac->RecvPending)
298             {
299                /*set the completion routines for the LLCP Transceive function*/
300                 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb;
301                 LlcpMac->MacCompletionInfo.Context = LlcpMac;
302 
303                 /* set the command type*/
304                 LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw;
305 
306                 /* set the Additional Info*/
307                 LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
308                 LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0;
309                 LlcpMac->SendPending = TRUE;
310 
311                 status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice,
312                                                     &LlcpMac->MacCompletionInfo,
313                                                     LlcpMac->psRemoteDevInfo,
314                                                     LlcpMac->Cmd,
315                                                     &LlcpMac->psDepAdditionalInfo,
316                                                     psData->buffer,
317                                                     (uint16_t)psData->length,
318                                                     LlcpMac->psReceiveBuffer->buffer,
319                                                     (uint16_t*)&LlcpMac->psReceiveBuffer->length);
320             }
321             else
322             {
323                LlcpMac->SendPending = TRUE;
324                LlcpMac->psSendBuffer = psData;
325                return status = NFCSTATUS_PENDING;
326             }
327          }break;
328       case phFriNfc_LlcpMac_ePeerTypeTarget:
329          {
330             if(!LlcpMac->RecvPending)
331             {
332                LlcpMac->SendPending = TRUE;
333                LlcpMac->psSendBuffer = psData;
334                return status = NFCSTATUS_PENDING;
335             }
336             else
337             {
338                /*set the completion routines for the LLCP Send function*/
339                LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Send_Cb;
340                LlcpMac->MacCompletionInfo.Context = LlcpMac;
341                status = phFriNfc_OvrHal_Send(LlcpMac->LowerDevice,
342                                              &LlcpMac->MacCompletionInfo,
343                                              LlcpMac->psRemoteDevInfo,
344                                              psData->buffer,
345                                              (uint16_t)psData->length);
346             }
347          }break;
348       default:
349          {
350             status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE);
351          }break;
352       }
353    }
354    return status;
355 }
356 
phFriNfc_LlcpMac_Nfcip_Receive(phFriNfc_LlcpMac_t * LlcpMac,phNfc_sData_t * psData,phFriNfc_LlcpMac_Reveive_CB_t LlcpMacReceive_Cb,void * pContext)357 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Receive(phFriNfc_LlcpMac_t               *LlcpMac,
358                                                 phNfc_sData_t                    *psData,
359                                                 phFriNfc_LlcpMac_Reveive_CB_t    LlcpMacReceive_Cb,
360                                                 void                             *pContext)
361 {
362    NFCSTATUS status = NFCSTATUS_SUCCESS;
363    if(NULL == LlcpMac || NULL==psData || NULL == LlcpMacReceive_Cb || NULL == pContext)
364    {
365       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
366    }
367    else if(LlcpMac->MacReceive_Cb != NULL)
368    {
369       /*Previous callback is pending */
370       status = NFCSTATUS_REJECTED;
371    }
372    else
373    {
374       /* Save the LlcpMacReceive_Cb */
375       LlcpMac->MacReceive_Cb = LlcpMacReceive_Cb;
376       LlcpMac->MacReceive_Context = pContext;
377 
378       /* Save the pointer to the receive buffer */
379       LlcpMac->psReceiveBuffer= psData;
380 
381       switch(LlcpMac->PeerRemoteDevType)
382       {
383       case phFriNfc_LlcpMac_ePeerTypeInitiator:
384          {
385             if(LlcpMac->SendPending)
386             {
387                /*set the completion routines for the LLCP Transceive function*/
388                LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb;
389                LlcpMac->MacCompletionInfo.Context = LlcpMac;
390                /* set the command type*/
391                LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw;
392                /* set the Additional Info*/
393                LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
394                LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0;
395                LlcpMac->RecvPending = TRUE;
396 
397                status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice,
398                                                    &LlcpMac->MacCompletionInfo,
399                                                    LlcpMac->psRemoteDevInfo,
400                                                    LlcpMac->Cmd,
401                                                    &LlcpMac->psDepAdditionalInfo,
402                                                    LlcpMac->psSendBuffer->buffer,
403                                                    (uint16_t)LlcpMac->psSendBuffer->length,
404                                                    psData->buffer,
405                                                    (uint16_t*)&psData->length);
406             }
407             else
408             {
409                LlcpMac->RecvPending = TRUE;
410                return status = NFCSTATUS_PENDING;
411             }
412          }break;
413       case phFriNfc_LlcpMac_ePeerTypeTarget:
414          {
415              /*set the completion routines for the LLCP Receive function*/
416             LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Receive_Cb;
417             /* save the context of LlcpMacNfcip */
418             LlcpMac->MacCompletionInfo.Context = LlcpMac;
419             LlcpMac->RecvPending = TRUE;
420 
421             status = phFriNfc_OvrHal_Receive(LlcpMac->LowerDevice,
422                                              &LlcpMac->MacCompletionInfo,
423                                              LlcpMac->psRemoteDevInfo,
424                                              LlcpMac->psReceiveBuffer->buffer,
425                                              (uint16_t*)&LlcpMac->psReceiveBuffer->length);
426          }break;
427       default:
428          {
429             status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE);
430          }break;
431       }
432    }
433    return status;
434 }
435 
436 
phFriNfc_LlcpMac_Nfcip_Register(phFriNfc_LlcpMac_t * LlcpMac)437 NFCSTATUS phFriNfc_LlcpMac_Nfcip_Register (phFriNfc_LlcpMac_t *LlcpMac)
438 {
439    NFCSTATUS status = NFCSTATUS_SUCCESS;
440 
441    if(NULL != LlcpMac)
442    {
443       LlcpMac->LlcpMacInterface.chk = phFriNfc_LlcpMac_Nfcip_Chk;
444       LlcpMac->LlcpMacInterface.activate   = phFriNfc_LlcpMac_Nfcip_Activate;
445       LlcpMac->LlcpMacInterface.deactivate = phFriNfc_LlcpMac_Nfcip_Deactivate;
446       LlcpMac->LlcpMacInterface.send = phFriNfc_LlcpMac_Nfcip_Send;
447       LlcpMac->LlcpMacInterface.receive = phFriNfc_LlcpMac_Nfcip_Receive;
448 
449       return NFCSTATUS_SUCCESS;
450    }
451    else
452    {
453       return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED);
454    }
455 }
456