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*/
64 STATIC void phLibNfc_RemoteDev_CheckPresence_Cb(void  *context,
65                                 NFCSTATUS status);
66 
67 /**Used for presence chk incase of mifare std tags*/
68 STATIC 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 */
phLibNfc_config_discovery_cb(void * context,NFCSTATUS status)78 void 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 */
phLibNfc_Mgt_ConfigureDiscovery(phLibNfc_eDiscoveryConfigMode_t DiscoveryMode,phLibNfc_sADD_Cfg_t sADDSetup,pphLibNfc_RspCb_t pConfigDiscovery_RspCb,void * pContext)142 NFCSTATUS 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 */
phLibNfc_RemoteDev_CheckPresence(phLibNfc_Handle hTargetDev,pphLibNfc_RspCb_t pPresenceChk_RspCb,void * pRspCbCtx)220 NFCSTATUS 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 */
311 STATIC
phLibNfc_RemoteDev_CheckPresence_Cb(void * context,NFCSTATUS status)312 void 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*/
phLibNfc_ChkPresence_Trcv_Cb(void * context,phHal_sRemoteDevInformation_t * psRemoteDevInfo,phNfc_sData_t * response,NFCSTATUS status)361 STATIC 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