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_discovery.c
19
20 * Project: NFC FRI 1.1
21 *
22 * $Date: Mon Mar  1 19:02:41 2010 $
23 * $Author: ing07385 $
24 * $Revision: 1.36 $
25 * $Aliases: 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#define STATIC
50#endif
51
52/*
53*************************** Global Variables **********************************
54*/
55
56
57
58/*
59*************************** Static Function Declaration ***********************
60*/
61
62
63/*Remote device Presence check callback*/
64STATIC void phLibNfc_RemoteDev_CheckPresence_Cb(void  *context,
65                                NFCSTATUS status);
66
67/**Used for presence chk incase of mifare std tags*/
68STATIC void phLibNfc_ChkPresence_Trcv_Cb(
69                            void *context,
70                            phHal_sRemoteDevInformation_t *psRemoteDevInfo,
71                            phNfc_sData_t *response,
72                            NFCSTATUS status
73                            );
74
75/*
76*************************** Function Definitions ******************************
77*/
78void phLibNfc_config_discovery_cb(void     *context,
79                                  NFCSTATUS status)
80{
81
82    if((phLibNfc_LibContext_t *)context == gpphLibContext)
83    {   /*check for same context*/
84
85        if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
86        {
87            /*If shutdown called in between allow shutdown to happen*/
88            phLibNfc_Pending_Shutdown();
89            status = NFCSTATUS_SHUTDOWN;
90        }
91        else
92        {
93            gpphLibContext->status.GenCb_pending_status = FALSE;
94            gpphLibContext->status.DiscEnbl_status = FALSE;
95            phLibNfc_UpdateCurState(status,gpphLibContext);
96#ifdef RESTART_CFG
97            if(gpphLibContext->status.Discovery_pending_status == TRUE)
98            {
99                NFCSTATUS RetStatus = NFCSTATUS_FAILED;
100                /* Application has called discovery before receiving this callback,
101                so NO notification to the upper layer, instead lower layer
102                discovery is called */
103                gpphLibContext->status.Discovery_pending_status = FALSE;
104                RetStatus =  phHal4Nfc_ConfigureDiscovery(
105                        gpphLibContext->psHwReference,
106                        gpphLibContext->eLibNfcCfgMode,
107                        &gpphLibContext->sADDconfig,
108                        (pphLibNfc_RspCb_t)
109                        phLibNfc_config_discovery_cb,
110                        (void *)gpphLibContext);
111                if (NFCSTATUS_PENDING == RetStatus)
112                {
113                    (void)phLibNfc_UpdateNextState(gpphLibContext,
114                                            eLibNfcHalStateConfigReady);
115                    gpphLibContext->status.GenCb_pending_status = TRUE;
116                    gpphLibContext->status.DiscEnbl_status = TRUE;
117                }
118                else
119                {
120                    status = NFCSTATUS_FAILED;
121                }
122            }
123#endif /* #ifdef RESTART_CFG */
124        }
125    } /*End of if-context check*/
126    else
127    {   /*exception: wrong context pointer returned*/
128        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
129        status = NFCSTATUS_FAILED;
130    }
131    if(gpphLibContext->CBInfo.pClientDisConfigCb!=NULL)
132    {
133        gpphLibContext->CBInfo.pClientDisConfigCb(gpphLibContext->CBInfo.pClientDisCfgCntx,status);
134        gpphLibContext->CBInfo.pClientDisConfigCb=NULL;
135    }
136    return;
137}
138/**
139* Configure Discovery Modes.
140* This function is used to configure ,start and stop the discovery wheel.
141*/
142NFCSTATUS phLibNfc_Mgt_ConfigureDiscovery (
143                        phLibNfc_eDiscoveryConfigMode_t DiscoveryMode,
144                        phLibNfc_sADD_Cfg_t             sADDSetup,
145                        pphLibNfc_RspCb_t               pConfigDiscovery_RspCb,
146                        void*                           pContext
147                        )
148 {
149    NFCSTATUS RetVal = NFCSTATUS_FAILED;
150    phHal_sADD_Cfg_t           *psADDConfig;
151    psADDConfig = (phHal_sADD_Cfg_t *)&(sADDSetup);
152
153
154   if((NULL == gpphLibContext) ||
155        (gpphLibContext->LibNfcState.cur_state
156                            == eLibNfcHalStateShutdown))
157    {
158        /*Lib Nfc not initialized*/
159        RetVal = NFCSTATUS_NOT_INITIALISED;
160    }
161    /* Check for Valid parameters*/
162    else if((NULL == pContext) || (NULL == pConfigDiscovery_RspCb))
163    {
164        RetVal= NFCSTATUS_INVALID_PARAMETER;
165    }
166    else if(gpphLibContext->LibNfcState.next_state
167                            == eLibNfcHalStateShutdown)
168    {
169        RetVal= NFCSTATUS_SHUTDOWN;
170    }
171    else
172    {
173        gpphLibContext->eLibNfcCfgMode =DiscoveryMode;
174        gpphLibContext->sADDconfig = sADDSetup;
175        if(gpphLibContext->status.DiscEnbl_status != TRUE)
176        {
177
178            /* call lower layer config API for the discovery
179            configuration sent by the application */
180            RetVal = phHal4Nfc_ConfigureDiscovery ( gpphLibContext->psHwReference,
181                                        DiscoveryMode,
182                                        psADDConfig,
183                                        (pphLibNfc_RspCb_t)
184                                        phLibNfc_config_discovery_cb,
185                                        (void*)gpphLibContext);
186            if(PHNFCSTATUS(RetVal) == NFCSTATUS_PENDING)
187            {
188                gpphLibContext->status.DiscEnbl_status = TRUE;
189                /* Copy discovery callback and its context */
190                gpphLibContext->CBInfo.pClientDisConfigCb = pConfigDiscovery_RspCb;
191                gpphLibContext->CBInfo.pClientDisCfgCntx = pContext;
192                gpphLibContext->status.GenCb_pending_status = TRUE;
193				gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConfigReady;
194            }
195            else
196            {
197                if (PHNFCSTATUS(RetVal) == NFCSTATUS_BUSY)
198                {
199                    RetVal = NFCSTATUS_BUSY;
200                }
201                else
202                {
203                    RetVal=NFCSTATUS_FAILED;
204                }
205            }
206
207        }
208        else
209        {
210            RetVal=NFCSTATUS_BUSY;
211        }
212    }
213    return RetVal;
214 }
215
216/**
217* Check for target presence.
218* Checks given target is present in RF filed or not
219*/
220NFCSTATUS phLibNfc_RemoteDev_CheckPresence( phLibNfc_Handle     hTargetDev,
221                                            pphLibNfc_RspCb_t   pPresenceChk_RspCb,
222                                            void*               pRspCbCtx
223                                           )
224{
225    NFCSTATUS RetVal = NFCSTATUS_FAILED;
226    phHal_sRemoteDevInformation_t *ps_rem_dev_info = NULL;
227    /* Check for valid sate */
228    if((NULL == gpphLibContext) ||
229        (gpphLibContext->LibNfcState.cur_state
230                            == eLibNfcHalStateShutdown))
231    {
232        RetVal = NFCSTATUS_NOT_INITIALISED;
233    }
234    /* Check for valid parameters*/
235    else if((NULL == pRspCbCtx) || (NULL == pPresenceChk_RspCb)
236        || (hTargetDev == 0) )
237    {
238        RetVal= NFCSTATUS_INVALID_PARAMETER;
239    }
240    /* Check for DeInit call*/
241    else if(gpphLibContext->LibNfcState.next_state
242                            == eLibNfcHalStateShutdown)
243    {
244        RetVal = NFCSTATUS_SHUTDOWN;
245    }
246    /* Check target is connected or not */
247    else if( gpphLibContext->Connected_handle == 0)
248    {
249        RetVal = NFCSTATUS_TARGET_NOT_CONNECTED;
250    }
251    /* Check given handle is valid or not*/
252    else if(hTargetDev != gpphLibContext->Connected_handle)
253    {
254        RetVal = NFCSTATUS_INVALID_HANDLE;
255    }
256#ifdef LLCP_TRANSACT_CHANGES
257    else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state)
258            && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state))
259    {
260        RetVal= NFCSTATUS_BUSY;
261    }
262#endif /* #ifdef LLCP_TRANSACT_CHANGES */
263    else
264    {
265        ps_rem_dev_info = (phHal_sRemoteDevInformation_t *)
266                                    gpphLibContext->Connected_handle;
267        if((phHal_eMifare_PICC == ps_rem_dev_info->RemDevType)
268            &&(0 != ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak)
269            &&(TRUE == gpphLibContext->LastTrancvSuccess))
270        {
271            /* Call HAL4 API */
272            RetVal =  phHal4Nfc_Transceive(
273                                gpphLibContext->psHwReference,
274                                gpphLibContext->psBufferedAuth,
275                                (phHal_sRemoteDevInformation_t *)
276                                    gpphLibContext->Connected_handle,
277                                (pphHal4Nfc_TransceiveCallback_t )
278                                    phLibNfc_ChkPresence_Trcv_Cb,
279                                (void *)gpphLibContext
280                                );
281
282        }
283        else
284        {
285            /* Call lower layer PresenceCheck function */
286            RetVal = phHal4Nfc_PresenceCheck(gpphLibContext->psHwReference,
287                                        phLibNfc_RemoteDev_CheckPresence_Cb,
288                                        (void *)gpphLibContext);
289        }
290        if( NFCSTATUS_PENDING == PHNFCSTATUS(RetVal))
291        {
292            gpphLibContext->CBInfo.pClientPresChkCb = pPresenceChk_RspCb;
293            gpphLibContext->CBInfo.pClientPresChkCntx = pRspCbCtx;
294            /* Mark General callback pending status as TRUE*/
295            gpphLibContext->status.GenCb_pending_status = TRUE;
296
297            /* Update the state machine*/
298			gpphLibContext->LibNfcState.next_state = eLibNfcHalStatePresenceChk;
299        }
300        else /* If return value is internal error(other than pending ) return NFCSTATUS_FAILED*/
301        {
302          RetVal = NFCSTATUS_FAILED;
303        }
304    }
305    return RetVal;
306}
307
308/**
309* Response Callback for Remote device Presence Check.
310*/
311STATIC
312void phLibNfc_RemoteDev_CheckPresence_Cb(void     *context,
313                                        NFCSTATUS status)
314{
315    void                    *pUpperLayerContext=NULL;
316    pphLibNfc_RspCb_t       pClientCb=NULL;
317
318    /*check valid context is returned or not*/
319    if((phLibNfc_LibContext_t *)context != gpphLibContext)
320    {
321        /*exception: wrong context pointer returned*/
322        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
323    }
324    /* Mark general callback pending status as FALSE*/
325    gpphLibContext->status.GenCb_pending_status = FALSE;
326    pClientCb =gpphLibContext->CBInfo.pClientPresChkCb ;
327    pUpperLayerContext = gpphLibContext->CBInfo.pClientPresChkCntx;
328    gpphLibContext->CBInfo.pClientPresChkCntx = NULL;
329    gpphLibContext->CBInfo.pClientPresChkCb =NULL;
330    /* Check DeInit call is called, if yes call pending
331    shutdown and return NFCSTATUS_SHUTDOWN */
332    if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
333    {
334        phLibNfc_Pending_Shutdown();
335        status = NFCSTATUS_SHUTDOWN;
336    }
337    else
338    {
339        if (status != NFCSTATUS_SUCCESS)
340        {
341           /*If status is other than SUCCESS (Internal error) return
342           NFCSTATUS_TARGET_LOST */
343            status= NFCSTATUS_TARGET_LOST;
344        }
345        else
346        {
347            status = NFCSTATUS_SUCCESS;
348        }
349    }
350     /* Update the current state */
351    phLibNfc_UpdateCurState(status,gpphLibContext);
352    if(NULL != pClientCb)
353    {
354        /* call the upper layer callback */
355        pClientCb(pUpperLayerContext,status);
356    }
357    return;
358}
359
360/**Used for presence chk incase of mifare std tags*/
361STATIC void phLibNfc_ChkPresence_Trcv_Cb(
362                            void *context,
363                            phHal_sRemoteDevInformation_t *psRemoteDevInfo,
364                            phNfc_sData_t *response,
365                            NFCSTATUS status
366                            )
367{
368    PHNFC_UNUSED_VARIABLE(psRemoteDevInfo);
369    PHNFC_UNUSED_VARIABLE(response);
370    phLibNfc_RemoteDev_CheckPresence_Cb(context,status);
371    return;
372}
373
374
375
376