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