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