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