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 * \file phLibNfc_Target.c
19
20 * Project: NFC FRI 1.1
21 *
22 * $Date: Thu Oct 15 15:24:43 2009 $
23 * $Author: ing07299 $
24 * $Revision: 1.12 $
25 * $Aliases: NFC_FRI1.1_WK943_R32_1,NFC_FRI1.1_WK944_SDK,NFC_FRI1.1_WK949_PREP1,NFC_FRI1.1_WK949_SDK_INT,NFC_FRI1.1_WK943_R32_10,NFC_FRI1.1_WK943_R32_13,NFC_FRI1.1_WK1003_SDK,NFC_FRI1.1_WK943_R32_14,NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1008_SDK,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1007_SDK,NFC_FRI1.1_WK1014_SDK,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1019_SDK,NFC_FRI1.1_WK1024_SDK $
26 *
27 */
28
29/*
30************************* Header Files ***************************************
31*/
32
33#include <phLibNfcStatus.h>
34#include <phLibNfc.h>
35#include <phHal4Nfc.h>
36#include <phOsalNfc.h>
37#include <phLibNfc_Internal.h>
38#include <phLibNfc_ndef_raw.h>
39#include <phLibNfc_initiator.h>
40#include <phLibNfc_discovery.h>
41
42/*
43*************************** Macro's  ****************************************
44*/
45
46#ifndef STATIC_DISABLE
47#define STATIC static
48#else
49//#undef STATIC
50#define STATIC
51#endif
52/*
53*************************** Global Variables **********************************
54*/
55
56/*
57*************************** Static Function Declaration ***********************
58*/
59
60/* Remote device receive callback */
61STATIC void phLibNfc_RemoteDev_Receive_Cb(
62                                void            *context,
63                                phNfc_sData_t   *rec_rsp_data,
64                                NFCSTATUS       status
65                                );
66
67/* Remote device Send callback */
68STATIC void phLibNfc_RemoteDev_Send_Cb(
69                                void        *Context,
70                                NFCSTATUS   status
71                                );
72
73/*
74*************************** Function Definitions ******************************
75*/
76
77/**
78* Interface used to receive data from initiator at target side during P2P
79* communication.
80*/
81NFCSTATUS phLibNfc_RemoteDev_Receive(phLibNfc_Handle       hRemoteDevice,
82                                pphLibNfc_Receive_RspCb_t  pReceiveRspCb,
83                                void                       *pContext
84                                )
85{
86    NFCSTATUS RetVal = NFCSTATUS_FAILED;
87    /*Check Lib Nfc is initialized*/
88    if((NULL == gpphLibContext)||
89        (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
90    {
91        RetVal = NFCSTATUS_NOT_INITIALISED;
92    }/*Check application has sent valid parameters*/
93    else if (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateRelease)
94    {
95        RetVal = NFCSTATUS_DESELECTED;
96    }
97    else if((NULL == pReceiveRspCb)
98        || (NULL == pContext)
99        || (0 == hRemoteDevice))
100    {
101        RetVal= NFCSTATUS_INVALID_PARAMETER;
102    }
103    else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown)
104    {
105        RetVal = NFCSTATUS_SHUTDOWN;
106    }
107    else if((TRUE == gpphLibContext->status.GenCb_pending_status)
108        ||(NULL!=gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb)
109        ||(phHal_eNfcIP1_Target==
110        ((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType))
111    {
112        /*Previous callback is pending or if initiator uses this api */
113        RetVal = NFCSTATUS_REJECTED;
114    }/*check for Discovered initiator handle and handle sent by application */
115    else if(gpphLibContext->sNfcIp_Context.Rem_Initiator_Handle != hRemoteDevice)
116    {
117        RetVal= NFCSTATUS_INVALID_DEVICE;
118    }
119#ifdef LLCP_TRANSACT_CHANGES
120    else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state)
121            && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state))
122    {
123        RetVal = NFCSTATUS_BUSY;
124    }
125#endif /* #ifdef LLCP_TRANSACT_CHANGES */
126    else
127    {
128        if(eLibNfcHalStatePresenceChk ==
129                gpphLibContext->LibNfcState.next_state)
130        {
131            gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb = NULL;
132            RetVal = NFCSTATUS_PENDING;
133        }
134        else
135        {
136            /*Call below layer receive and register the callback with it*/
137            PHDBG_INFO("LibNfc:P2P Receive In Progress");
138            RetVal =phHal4Nfc_Receive(
139                            gpphLibContext->psHwReference,
140                            (phHal4Nfc_TransactInfo_t*)gpphLibContext->psTransInfo,
141                            (pphLibNfc_Receive_RspCb_t)
142                            phLibNfc_RemoteDev_Receive_Cb,
143                            (void *)gpphLibContext
144                            );
145        }
146        if(NFCSTATUS_PENDING == RetVal)
147        {
148            /*Update the Next state as Transaction*/
149            gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb= pReceiveRspCb;
150            gpphLibContext->sNfcIp_Context.pClientNfcIpRxCntx = pContext;
151            gpphLibContext->status.GenCb_pending_status=TRUE;
152            gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction;
153        }
154        else
155        {
156            RetVal = NFCSTATUS_FAILED;
157        }
158    }
159    return RetVal;
160}
161/**
162* Response callback for Remote Device Receive.
163*/
164STATIC void phLibNfc_RemoteDev_Receive_Cb(
165                                    void            *context,
166                                    phNfc_sData_t   *rec_rsp_data,
167                                    NFCSTATUS       status
168                                    )
169{
170    pphLibNfc_Receive_RspCb_t       pClientCb=NULL;
171
172    phLibNfc_LibContext_t   *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)context;
173    void                    *pUpperLayerContext=NULL;
174
175    /* Check for the context returned by below layer */
176    if(pLibNfc_Ctxt != gpphLibContext)
177    {   /*wrong context returned*/
178        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
179    }
180    else
181    {
182        pClientCb = gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb;
183        pUpperLayerContext = gpphLibContext->sNfcIp_Context.pClientNfcIpRxCntx;
184
185        gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb = NULL;
186        gpphLibContext->sNfcIp_Context.pClientNfcIpRxCntx = NULL;
187        gpphLibContext->status.GenCb_pending_status = FALSE;
188        if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
189        {   /*shutdown called before completion of P2P receive allow
190              shutdown to happen */
191            phLibNfc_Pending_Shutdown();
192            status = NFCSTATUS_SHUTDOWN;
193        }
194        else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
195        {
196            status = NFCSTATUS_ABORTED;
197        }
198        else
199        {
200            if((NFCSTATUS_SUCCESS != status) &&
201                (PHNFCSTATUS(status) != NFCSTATUS_MORE_INFORMATION ) )
202            {
203                /*During p2p receive operation initiator was removed
204                from RF field of target*/
205                status = NFCSTATUS_DESELECTED;
206            }
207            else
208            {
209                status = NFCSTATUS_SUCCESS;
210            }
211        }
212        /* Update current state */
213        phLibNfc_UpdateCurState(status,gpphLibContext);
214
215        if (NULL != pClientCb)
216        {
217            /*Notify to upper layer status and No. of bytes
218             actually received */
219            pClientCb(pUpperLayerContext, rec_rsp_data, status);
220        }
221    }
222    return;
223}
224
225/**
226* Interface used to send data from target to initiator during P2P communication
227*/
228NFCSTATUS
229phLibNfc_RemoteDev_Send(
230                        phLibNfc_Handle      hRemoteDevice,
231                        phNfc_sData_t *      pTransferData,
232                        pphLibNfc_RspCb_t    pSendRspCb,
233                        void                 *pContext
234                        )
235{
236    NFCSTATUS RetVal = NFCSTATUS_FAILED;
237    /*Check Lib Nfc stack is initilized*/
238    if((NULL == gpphLibContext)||
239        (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
240    {
241        RetVal = NFCSTATUS_NOT_INITIALISED;
242    }
243    else if (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateRelease)
244    {
245        RetVal = NFCSTATUS_DESELECTED;
246    }
247    /*Check application has sent the valid parameters*/
248    else if((NULL == pTransferData)
249        || (NULL == pSendRspCb)
250        || (NULL == pTransferData->buffer)
251        || (0 == pTransferData->length)
252        || (NULL == pContext)
253        || (0 == hRemoteDevice))
254    {
255        RetVal= NFCSTATUS_INVALID_PARAMETER;
256    }
257    else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown)
258    {
259        RetVal = NFCSTATUS_SHUTDOWN;
260    }
261	else if((TRUE == gpphLibContext->status.GenCb_pending_status)
262        ||(NULL!=gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb)
263        ||(phHal_eNfcIP1_Target==
264        ((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType))
265    {
266        /*Previous callback is pending or local device is Initiator
267        then don't allow */
268        RetVal = NFCSTATUS_REJECTED;
269    }/*Check for Discovered initiator handle and handle sent by application */
270    else if(gpphLibContext->sNfcIp_Context.Rem_Initiator_Handle != hRemoteDevice)
271    {
272        RetVal= NFCSTATUS_INVALID_DEVICE;
273    }
274    else if((NULL!=gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb))
275    {
276        RetVal =NFCSTATUS_BUSY ;
277    }
278#ifdef LLCP_TRANSACT_CHANGES
279    else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state)
280            && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state))
281    {
282        RetVal= NFCSTATUS_BUSY;
283    }
284#endif /* #ifdef LLCP_TRANSACT_CHANGES */
285    else
286    {
287        if(eLibNfcHalStatePresenceChk ==
288                gpphLibContext->LibNfcState.next_state)
289        {
290            gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb = NULL;
291            RetVal = NFCSTATUS_PENDING;
292        }
293        else
294        {
295            if(gpphLibContext->psTransInfo!=NULL)
296            {
297                (void)memset(gpphLibContext->psTransInfo,
298                                0,
299                                sizeof(phLibNfc_sTransceiveInfo_t));
300
301                gpphLibContext->psTransInfo->addr =UNKNOWN_BLOCK_ADDRESS;
302                /*pointer to send data */
303                gpphLibContext->psTransInfo->sSendData.buffer =
304                                                    pTransferData->buffer;
305                /*size of send data*/
306                gpphLibContext->psTransInfo->sSendData.length =
307                                                    pTransferData->length;
308
309                /* Copy remote device type */
310                gpphLibContext->sNfcIp_Context.TransactInfoRole.remotePCDType =
311                    ((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType;
312                /*Call Hal4 Send API and register callback with it*/
313                PHDBG_INFO("LibNfc:P2P send In Progress");
314                RetVal= phHal4Nfc_Send(
315                                gpphLibContext->psHwReference,
316                                &(gpphLibContext->sNfcIp_Context.TransactInfoRole),
317                                gpphLibContext->psTransInfo->sSendData,
318                                (pphLibNfc_RspCb_t)
319                                phLibNfc_RemoteDev_Send_Cb,
320                                (void *)gpphLibContext
321                                );
322            }
323        }
324        if(NFCSTATUS_PENDING == RetVal)
325        {
326            /* Update next state to transaction */
327            gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb= pSendRspCb;
328            gpphLibContext->sNfcIp_Context.pClientNfcIpTxCntx = pContext;
329            gpphLibContext->status.GenCb_pending_status=TRUE;
330            gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction;
331        }
332        else
333        {
334            RetVal = NFCSTATUS_FAILED;
335        }
336    }
337    return RetVal;
338}
339
340/*
341* Response callback for Remote Device Send.
342*/
343STATIC void phLibNfc_RemoteDev_Send_Cb(
344                            void        *Context,
345                            NFCSTATUS   status
346                            )
347{
348    pphLibNfc_RspCb_t       pClientCb=NULL;
349    phLibNfc_LibContext_t   *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)Context;
350    void                    *pUpperLayerContext=NULL;
351
352    /* Check for the context returned by below layer */
353    if(pLibNfc_Ctxt != gpphLibContext)
354    {   /*wrong context returned*/
355        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
356    }
357    else
358    {
359        if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
360        {   /*shutdown called before completion p2p send allow
361              shutdown to happen */
362            phLibNfc_Pending_Shutdown();
363            status = NFCSTATUS_SHUTDOWN;
364        }
365        else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
366        {
367            status = NFCSTATUS_ABORTED;
368        }
369        else
370        {
371            gpphLibContext->status.GenCb_pending_status = FALSE;
372            if((NFCSTATUS_SUCCESS != status) &&
373                (PHNFCSTATUS(status) != NFCSTATUS_MORE_INFORMATION ) )
374            {
375                /*During p2p send operation initator was not present in RF
376                field of target*/
377                status = NFCSTATUS_DESELECTED;
378            }
379            else
380            {
381                status = NFCSTATUS_SUCCESS;
382            }
383        }
384        /* Update current state */
385        phLibNfc_UpdateCurState(status,gpphLibContext);
386
387        pClientCb = gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb;
388        pUpperLayerContext = gpphLibContext->sNfcIp_Context.pClientNfcIpTxCntx;
389
390        gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb = NULL;
391        gpphLibContext->sNfcIp_Context.pClientNfcIpTxCntx = NULL;
392        if (NULL != pClientCb)
393        {
394            /* Notify to upper layer status and No. of bytes
395             actually written or send to initiator */
396            pClientCb(pUpperLayerContext, status);
397        }
398    }
399    return;
400}
401
402
403
404
405