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