2 * Copyright (C) 2010 NXP Semiconductors
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * \file phFriNfc_LlcpMacNfcip.c
20 * \brief NFC LLCP MAC Mappings For Different RF Technologies.
28 #include <phFriNfc_LlcpMac.h>
29 #include <phLibNfcStatus.h>
31 #include <phLibNfc_Internal.h>
35 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t *LlcpMac,
36 phNfc_sData_t *psData,
37 phFriNfc_LlcpMac_Send_CB_t LlcpMacSend_Cb,
41 static void phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(phFriNfc_LlcpMac_t *LlcpMac,
44 phFriNfc_LlcpMac_Reveive_CB_t pfReceiveCB;
45 void *pReceiveContext;
47 if (LlcpMac->MacReceive_Cb != NULL)
49 /* Save callback params */
50 pfReceiveCB = LlcpMac->MacReceive_Cb;
51 pReceiveContext = LlcpMac->MacReceive_Context;
53 /* Reset the pointer to the Receive Callback and Context*/
54 LlcpMac->MacReceive_Cb = NULL;
55 LlcpMac->MacReceive_Context = NULL;
57 /* Call the receive callback */
58 pfReceiveCB(pReceiveContext, status, LlcpMac->psReceiveBuffer);
62 static void phFriNfc_LlcpMac_Nfcip_TriggerSendCb(phFriNfc_LlcpMac_t *LlcpMac,
65 phFriNfc_LlcpMac_Send_CB_t pfSendCB;
68 if (LlcpMac->MacSend_Cb != NULL)
70 /* Save context in local variables */
71 pfSendCB = LlcpMac->MacSend_Cb;
72 pSendContext = LlcpMac->MacSend_Context;
74 /* Reset the pointer to the Send Callback */
75 LlcpMac->MacSend_Cb = NULL;
76 LlcpMac->MacSend_Context = NULL;
78 /* Call Send callback */
79 pfSendCB(pSendContext, status);
83 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Chk(phFriNfc_LlcpMac_t *LlcpMac,
84 phFriNfc_LlcpMac_Chk_CB_t ChkLlcpMac_Cb,
88 NFCSTATUS status = NFCSTATUS_SUCCESS;
89 uint8_t Llcp_Magic_Number[] = {0x46,0x66,0x6D};
91 if(NULL == LlcpMac || NULL == ChkLlcpMac_Cb || NULL == pContext)
93 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
97 ret = memcmp(Llcp_Magic_Number,LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo,3);
100 LlcpMac->sConfigParam.buffer = &LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo[3] ;
101 LlcpMac->sConfigParam.length = (LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length - 3);
102 status = NFCSTATUS_SUCCESS;
106 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED);
110 ChkLlcpMac_Cb(pContext,status);
114 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Activate (phFriNfc_LlcpMac_t *LlcpMac)
116 NFCSTATUS status = NFCSTATUS_SUCCESS;
120 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
124 LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkActivated;
125 LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context,
127 &LlcpMac->sConfigParam,
128 LlcpMac->PeerRemoteDevType);
134 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Deactivate (phFriNfc_LlcpMac_t *LlcpMac)
136 NFCSTATUS status = NFCSTATUS_SUCCESS;
140 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
144 /* Set the flag of LinkStatus to deactivate */
145 LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkDeactivated;
148 if (LlcpMac->SendPending)
151 LlcpMac->SendPending = FALSE;
153 phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, NFCSTATUS_FAILED);
156 if (LlcpMac->RecvPending)
159 LlcpMac->RecvPending = FALSE;
161 phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, NFCSTATUS_FAILED);
164 LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context,
167 LlcpMac->PeerRemoteDevType);
172 static void phFriNfc_LlcpMac_Nfcip_Send_Cb(void *pContext,
175 phFriNfc_LlcpMac_t *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
178 if(gpphLibContext->LibNfcState.next_state
179 == eLibNfcHalStateShutdown)
181 phLibNfc_Pending_Shutdown();
182 Status = NFCSTATUS_SHUTDOWN;
184 #endif /* #ifdef LLCP_CHANGES */
186 /* Reset Send and Receive Flag */
187 LlcpMac->SendPending = FALSE;
188 LlcpMac->RecvPending = FALSE;
190 phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status);
194 static void phFriNfc_LlcpMac_Nfcip_Receive_Cb(void *pContext,
197 phFriNfc_LlcpMac_t *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
200 phFriNfc_LlcpMac_Send_CB_t pfSendCB;
204 if(gpphLibContext->LibNfcState.next_state
205 == eLibNfcHalStateShutdown)
207 phLibNfc_Pending_Shutdown();
208 Status = NFCSTATUS_SHUTDOWN;
211 if (NFCSTATUS_SHUTDOWN == Status)
213 /* Save context in local variables */
214 pfSendCB = LlcpMac->MacSend_Cb;
215 pSendContext = LlcpMac->MacSend_Context;
217 /* Reset the pointer to the Send Callback */
218 LlcpMac->MacSend_Cb = NULL;
219 LlcpMac->MacSend_Context = NULL;
221 /* Reset Send and Receive Flag */
222 LlcpMac->SendPending = FALSE;
223 LlcpMac->RecvPending = FALSE;
226 #endif /* #ifdef LLCP_CHANGES */
228 phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status);
232 if (NFCSTATUS_SHUTDOWN == Status)
234 if ((LlcpMac->SendPending) && (NULL != pfSendCB))
236 pfSendCB(pSendContext, Status);
241 #endif /* #ifdef LLCP_CHANGES */
243 /* Test if a send is pending */
244 if(LlcpMac->SendPending)
246 Status = phFriNfc_LlcpMac_Nfcip_Send(LlcpMac,LlcpMac->psSendBuffer,LlcpMac->MacSend_Cb,LlcpMac->MacSend_Context);
251 static void phFriNfc_LlcpMac_Nfcip_Transceive_Cb(void *pContext,
254 phFriNfc_LlcpMac_t *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
257 if(gpphLibContext->LibNfcState.next_state
258 == eLibNfcHalStateShutdown)
260 phLibNfc_Pending_Shutdown();
261 Status = NFCSTATUS_SHUTDOWN;
263 #endif /* #ifdef LLCP_CHANGES */
265 /* Reset Send and Receive Flag */
266 LlcpMac->SendPending = FALSE;
267 LlcpMac->RecvPending = FALSE;
269 /* Call the callbacks */
270 phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status);
271 phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status);
274 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t *LlcpMac,
275 phNfc_sData_t *psData,
276 phFriNfc_LlcpMac_Send_CB_t LlcpMacSend_Cb,
279 NFCSTATUS status = NFCSTATUS_SUCCESS;
281 if(NULL == LlcpMac || NULL == psData || NULL == LlcpMacSend_Cb || NULL == pContext)
283 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
285 else if(LlcpMac->MacSend_Cb != NULL && LlcpMac->PeerRemoteDevType == phFriNfc_LlcpMac_ePeerTypeInitiator)
287 /*Previous callback is pending */
288 status = NFCSTATUS_REJECTED;
292 /* Save the LlcpMacSend_Cb */
293 LlcpMac->MacSend_Cb = LlcpMacSend_Cb;
294 LlcpMac->MacSend_Context = pContext;
296 switch(LlcpMac->PeerRemoteDevType)
298 case phFriNfc_LlcpMac_ePeerTypeInitiator:
300 if(LlcpMac->RecvPending)
302 /*set the completion routines for the LLCP Transceive function*/
303 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb;
304 LlcpMac->MacCompletionInfo.Context = LlcpMac;
306 /* set the command type*/
307 LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw;
309 /* set the Additional Info*/
310 LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
311 LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0;
312 LlcpMac->SendPending = TRUE;
314 status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice,
315 &LlcpMac->MacCompletionInfo,
316 LlcpMac->psRemoteDevInfo,
318 &LlcpMac->psDepAdditionalInfo,
320 (uint16_t)psData->length,
321 LlcpMac->psReceiveBuffer->buffer,
322 (uint16_t*)&LlcpMac->psReceiveBuffer->length);
326 LlcpMac->SendPending = TRUE;
327 LlcpMac->psSendBuffer = psData;
328 return status = NFCSTATUS_PENDING;
331 case phFriNfc_LlcpMac_ePeerTypeTarget:
333 if(!LlcpMac->RecvPending)
335 LlcpMac->SendPending = TRUE;
336 LlcpMac->psSendBuffer = psData;
337 return status = NFCSTATUS_PENDING;
341 /*set the completion routines for the LLCP Send function*/
342 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Send_Cb;
343 LlcpMac->MacCompletionInfo.Context = LlcpMac;
344 status = phFriNfc_OvrHal_Send(LlcpMac->LowerDevice,
345 &LlcpMac->MacCompletionInfo,
346 LlcpMac->psRemoteDevInfo,
348 (uint16_t)psData->length);
353 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE);
360 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Receive(phFriNfc_LlcpMac_t *LlcpMac,
361 phNfc_sData_t *psData,
362 phFriNfc_LlcpMac_Reveive_CB_t LlcpMacReceive_Cb,
365 NFCSTATUS status = NFCSTATUS_SUCCESS;
366 if(NULL == LlcpMac || NULL==psData || NULL == LlcpMacReceive_Cb || NULL == pContext)
368 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
370 else if(LlcpMac->MacReceive_Cb != NULL)
372 /*Previous callback is pending */
373 status = NFCSTATUS_REJECTED;
377 /* Save the LlcpMacReceive_Cb */
378 LlcpMac->MacReceive_Cb = LlcpMacReceive_Cb;
379 LlcpMac->MacReceive_Context = pContext;
381 /* Save the pointer to the receive buffer */
382 LlcpMac->psReceiveBuffer= psData;
384 switch(LlcpMac->PeerRemoteDevType)
386 case phFriNfc_LlcpMac_ePeerTypeInitiator:
388 if(LlcpMac->SendPending)
390 /*set the completion routines for the LLCP Transceive function*/
391 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb;
392 LlcpMac->MacCompletionInfo.Context = LlcpMac;
393 /* set the command type*/
394 LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw;
395 /* set the Additional Info*/
396 LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
397 LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0;
398 LlcpMac->RecvPending = TRUE;
400 status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice,
401 &LlcpMac->MacCompletionInfo,
402 LlcpMac->psRemoteDevInfo,
404 &LlcpMac->psDepAdditionalInfo,
405 LlcpMac->psSendBuffer->buffer,
406 (uint16_t)LlcpMac->psSendBuffer->length,
408 (uint16_t*)&psData->length);
412 LlcpMac->RecvPending = TRUE;
413 return status = NFCSTATUS_PENDING;
416 case phFriNfc_LlcpMac_ePeerTypeTarget:
418 /*set the completion routines for the LLCP Receive function*/
419 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Receive_Cb;
420 /* save the context of LlcpMacNfcip */
421 LlcpMac->MacCompletionInfo.Context = LlcpMac;
422 LlcpMac->RecvPending = TRUE;
424 status = phFriNfc_OvrHal_Receive(LlcpMac->LowerDevice,
425 &LlcpMac->MacCompletionInfo,
426 LlcpMac->psRemoteDevInfo,
427 LlcpMac->psReceiveBuffer->buffer,
428 (uint16_t*)&LlcpMac->psReceiveBuffer->length);
432 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE);
440 NFCSTATUS phFriNfc_LlcpMac_Nfcip_Register (phFriNfc_LlcpMac_t *LlcpMac)
442 NFCSTATUS status = NFCSTATUS_SUCCESS;
446 LlcpMac->LlcpMacInterface.chk = phFriNfc_LlcpMac_Nfcip_Chk;
447 LlcpMac->LlcpMacInterface.activate = phFriNfc_LlcpMac_Nfcip_Activate;
448 LlcpMac->LlcpMacInterface.deactivate = phFriNfc_LlcpMac_Nfcip_Deactivate;
449 LlcpMac->LlcpMacInterface.send = phFriNfc_LlcpMac_Nfcip_Send;
450 LlcpMac->LlcpMacInterface.receive = phFriNfc_LlcpMac_Nfcip_Receive;
452 return NFCSTATUS_SUCCESS;
456 return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED);