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