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 }
108
109 ChkLlcpMac_Cb(pContext,status);
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
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
phFriNfc_LlcpMac_Nfcip_Send_Cb(void * pContext,NFCSTATUS Status)171 static 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
phFriNfc_LlcpMac_Nfcip_Receive_Cb(void * pContext,NFCSTATUS Status)193 static 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->MacSend_Context);
246 }
247 }
248 }
249
phFriNfc_LlcpMac_Nfcip_Transceive_Cb(void * pContext,NFCSTATUS Status)250 static 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
phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t * LlcpMac,phNfc_sData_t * psData,phFriNfc_LlcpMac_Send_CB_t LlcpMacSend_Cb,void * pContext)273 static 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
phFriNfc_LlcpMac_Nfcip_Receive(phFriNfc_LlcpMac_t * LlcpMac,phNfc_sData_t * psData,phFriNfc_LlcpMac_Reveive_CB_t LlcpMacReceive_Cb,void * pContext)359 static 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
phFriNfc_LlcpMac_Nfcip_Register(phFriNfc_LlcpMac_t * LlcpMac)439 NFCSTATUS 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