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