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 * \file phHal4Nfc_P2P.c
18 * \brief Hal4Nfc_P2P source.
19 *
20 * Project: NFC-FRI 1.1
21 *
22 * $Date: Mon May 31 11:43:43 2010 $
23 * $Author: ing07385 $
24 * $Revision: 1.56 $
25 * $Aliases: NFC_FRI1.1_WK1023_R35_1 $
26 *
27 */
28
29 /* ---------------------------Include files ------------------------------------*/
30 #include <phHal4Nfc.h>
31 #include <phHal4Nfc_Internal.h>
32 #include <phOsalNfc.h>
33 #include <phOsalNfc_Timer.h>
34 #include <phHciNfc.h>
35 #include <phNfcConfig.h>
36
37 /* ------------------------------- Macros ------------------------------------*/
38
39 #ifdef _WIN32
40 /*Timeout value for recv data timer for P2P.This timer is used for creating
41 Asynchronous behavior in the scenario where the data is received even before
42 the upper layer calls the phHal4Nfc_receive().*/
43 #define PH_HAL4NFC_RECV_CB_TIMEOUT 100U
44 #else
45 #define PH_HAL4NFC_RECV_CB_TIMEOUT 0x00U
46 #endif/*#ifdef _WIN32*/
47
48
49 /* --------------------Structures and enumerations --------------------------*/
50
51 /*timer callback to send already buffered receive data to upper layer*/
52 static void phHal4Nfc_P2PRecvTimerCb(uint32_t P2PRecvTimerId, void *pContext);
53
54 /* ---------------------- Function definitions ------------------------------*/
55
56 /* Transfer the user data to another NfcIP device from the host.
57 * pTransferCallback is called, when all steps in the transfer sequence are
58 * completed.*/
59 NFCSTATUS
phHal4Nfc_Send(phHal_sHwReference_t * psHwReference,phHal4Nfc_TransactInfo_t * psTransferInfo,phNfc_sData_t sTransferData,pphHal4Nfc_SendCallback_t pSendCallback,void * pContext)60 phHal4Nfc_Send(
61 phHal_sHwReference_t *psHwReference,
62 phHal4Nfc_TransactInfo_t *psTransferInfo,
63 phNfc_sData_t sTransferData,
64 pphHal4Nfc_SendCallback_t pSendCallback,
65 void *pContext
66 )
67 {
68 NFCSTATUS RetStatus = NFCSTATUS_PENDING;
69 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
70
71 /*NULL checks*/
72 if((NULL == psHwReference)
73 ||( NULL == pSendCallback )
74 || (NULL == psTransferInfo)
75 )
76 {
77 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
78 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
79 }
80 /*Check initialised state*/
81 else if((NULL == psHwReference->hal_context)
82 || (((phHal4Nfc_Hal4Ctxt_t *)
83 psHwReference->hal_context)->Hal4CurrentState
84 < eHal4StateOpenAndReady)
85 || (((phHal4Nfc_Hal4Ctxt_t *)
86 psHwReference->hal_context)->Hal4NextState
87 == eHal4StateClosed))
88 {
89 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED);
90 }
91 /*Only NfcIp1 Target can call this API*/
92 else if(phHal_eNfcIP1_Initiator != psTransferInfo->remotePCDType)
93 {
94 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_DEVICE);
95 }
96 else
97 {
98 Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
99 if(NULL == Hal4Ctxt->psTrcvCtxtInfo)
100 {
101 RetStatus= PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_FAILED);
102 }
103 /*Check Activated*/
104 else if(NFC_EVT_ACTIVATED == Hal4Ctxt->sTgtConnectInfo.EmulationState)
105 {
106 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
107 /*Register upper layer callback*/
108 Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb = pSendCallback;
109 PHDBG_INFO("NfcIP1 Send");
110 /*allocate buffer to store senddata received from upper layer*/
111 if (NULL == Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData)
112 {
113 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData = (phNfc_sData_t *)
114 phOsalNfc_GetMemory(sizeof(phNfc_sData_t));
115 if(NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData)
116 {
117 (void)memset(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData, 0,
118 sizeof(phNfc_sData_t));
119 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
120 = PH_OSALNFC_INVALID_TIMER_ID;
121 }
122 }
123
124 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer
125 = sTransferData.buffer;
126 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length
127 = sTransferData.length;
128
129 /* If data size is less than Peer's Max frame length, then no chaining is required */
130 if(Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength >= sTransferData.length)
131 {
132 Hal4Ctxt->psTrcvCtxtInfo->
133 XchangeInfo.params.nfc_info.more_info = FALSE;
134 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length
135 = (uint8_t)sTransferData.length;
136 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer
137 = sTransferData.buffer;
138 }
139 else/*set more_info to true,to indicate more data pending to be sent*/
140 {
141 Hal4Ctxt->psTrcvCtxtInfo->
142 XchangeInfo.params.nfc_info.more_info = TRUE;
143 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length
144 = Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength;
145 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer
146 = sTransferData.buffer;
147 Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent
148 += Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength;
149 }
150 PHDBG_INFO("HAL4:Calling Hci_Send_data()");
151 RetStatus = phHciNfc_Send_Data (
152 Hal4Ctxt->psHciHandle,
153 psHwReference,
154 NULL,
155 &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo)
156 );
157 /*check return status*/
158 if (NFCSTATUS_PENDING == RetStatus)
159 {
160 /*Set P2P_Send_In_Progress to defer any disconnect call until
161 Send complete occurs*/
162 Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress = TRUE;
163 Hal4Ctxt->Hal4NextState = eHal4StateTransaction;
164 /*No of bytes remaining for next send*/
165 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length
166 -= Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length;
167 }
168 }
169 else/*Deactivated*/
170 {
171 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_DESELECTED);
172 }
173 }
174 return RetStatus;
175 }
176
177
178 /* Transfer the user data to the another NfcIP device from the host.
179 * pTransferCallback is called, when all steps in the transfer sequence are
180 * completed.*/
181
182 NFCSTATUS
phHal4Nfc_Receive(phHal_sHwReference_t * psHwReference,phHal4Nfc_TransactInfo_t * psRecvInfo,pphHal4Nfc_ReceiveCallback_t pReceiveCallback,void * pContext)183 phHal4Nfc_Receive(
184 phHal_sHwReference_t *psHwReference,
185 phHal4Nfc_TransactInfo_t *psRecvInfo,
186 pphHal4Nfc_ReceiveCallback_t pReceiveCallback,
187 void *pContext
188 )
189 {
190 NFCSTATUS RetStatus = NFCSTATUS_PENDING;
191 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
192 /*NULL checks*/
193 if((NULL == psHwReference)
194 ||( NULL == pReceiveCallback)
195 ||( NULL == psRecvInfo))
196 {
197 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
198 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
199 }
200 /*Check initialised state*/
201 else if((NULL == psHwReference->hal_context)
202 || (((phHal4Nfc_Hal4Ctxt_t *)
203 psHwReference->hal_context)->Hal4CurrentState
204 < eHal4StateOpenAndReady)
205 || (((phHal4Nfc_Hal4Ctxt_t *)
206 psHwReference->hal_context)->Hal4NextState
207 == eHal4StateClosed))
208 {
209 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED);
210 }
211 else
212 {
213 Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
214 if(NFC_EVT_ACTIVATED == Hal4Ctxt->sTgtConnectInfo.EmulationState)
215 {
216 /*Following condition gets satisfied only on target side,if receive
217 is not already called*/
218 if(NULL == Hal4Ctxt->psTrcvCtxtInfo)
219 {
220 Hal4Ctxt->psTrcvCtxtInfo= (pphHal4Nfc_TrcvCtxtInfo_t)
221 phOsalNfc_GetMemory((uint32_t)
222 (sizeof(phHal4Nfc_TrcvCtxtInfo_t)));
223 if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
224 {
225 (void)memset(Hal4Ctxt->psTrcvCtxtInfo,0,
226 sizeof(phHal4Nfc_TrcvCtxtInfo_t));
227 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
228 = PH_OSALNFC_INVALID_TIMER_ID;
229 Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus = NFCSTATUS_PENDING;
230 }
231 }
232 if(NULL == Hal4Ctxt->psTrcvCtxtInfo)
233 {
234 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
235 RetStatus= PHNFCSTVAL(CID_NFC_HAL ,
236 NFCSTATUS_INSUFFICIENT_RESOURCES);
237 }
238 else /*Store callback & Return status pending*/
239 {
240 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
241 /*Register upper layer callback*/
242 Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL;
243 Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb = pReceiveCallback;
244 if(NFCSTATUS_PENDING !=
245 Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus)
246 {
247 /**Create a timer to send received data in the callback*/
248 if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
249 == PH_OSALNFC_INVALID_TIMER_ID)
250 {
251 PHDBG_INFO("HAL4: Transaction Timer Create for Receive");
252 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
253 = phOsalNfc_Timer_Create();
254 }
255 if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
256 == PH_OSALNFC_INVALID_TIMER_ID)
257 {
258 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,
259 NFCSTATUS_INSUFFICIENT_RESOURCES);
260 }
261 else/*start the timer*/
262 {
263 phOsalNfc_Timer_Start(
264 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId,
265 PH_HAL4NFC_RECV_CB_TIMEOUT,
266 phHal4Nfc_P2PRecvTimerCb,
267 NULL
268 );
269 }
270 }
271 }
272 }
273 else/*deactivated*/
274 {
275 RetStatus= PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_DESELECTED);
276 }
277 }
278 return RetStatus;
279 }
280
281 /*Timer callback for recv data timer for P2P.This timer is used for creating
282 Asynchronous behavior in the scenario where the data is received even before
283 the upper layer calls the phHal4Nfc_receive().*/
phHal4Nfc_P2PRecvTimerCb(uint32_t P2PRecvTimerId,void * pContext)284 static void phHal4Nfc_P2PRecvTimerCb(uint32_t P2PRecvTimerId, void *pContext)
285 {
286 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)(
287 gpphHal4Nfc_Hwref->hal_context);
288 pphHal4Nfc_ReceiveCallback_t pUpperRecvCb = NULL;
289 NFCSTATUS RecvDataBufferStatus = NFCSTATUS_PENDING;
290 PHNFC_UNUSED_VARIABLE(pContext);
291
292 phOsalNfc_Timer_Stop(P2PRecvTimerId);
293 phOsalNfc_Timer_Delete(P2PRecvTimerId);
294 if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
295 {
296 RecvDataBufferStatus = Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus;
297 Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus = NFCSTATUS_PENDING;
298
299 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
300 = PH_OSALNFC_INVALID_TIMER_ID;
301 /*Update state*/
302 Hal4Ctxt->Hal4NextState = (eHal4StateTransaction
303 == Hal4Ctxt->Hal4NextState?eHal4StateInvalid:Hal4Ctxt->Hal4NextState);
304 /*Provide address of received data to upper layer data pointer*/
305 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData
306 = &(Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData);
307 /*Chk NULL and call recv callback*/
308 if(Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb != NULL)
309 {
310 pUpperRecvCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb;
311 Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb = NULL;
312 (*pUpperRecvCb)(
313 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
314 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData,
315 RecvDataBufferStatus
316 );
317 }
318 }
319 return;
320 }
321
322 /**Send complete handler*/
phHal4Nfc_SendCompleteHandler(phHal4Nfc_Hal4Ctxt_t * Hal4Ctxt,void * pInfo)323 void phHal4Nfc_SendCompleteHandler(phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,void *pInfo)
324 {
325 pphHal4Nfc_SendCallback_t pUpperSendCb = NULL;
326 pphHal4Nfc_TransceiveCallback_t pUpperTrcvCb = NULL;
327 NFCSTATUS SendStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status;
328 pphHal4Nfc_DiscntCallback_t pUpperDisconnectCb = NULL;
329 Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress = FALSE;
330 /*Send status Success or Pending disconnect in HAl4*/
331 if((SendStatus != NFCSTATUS_SUCCESS)
332 ||(NFC_INVALID_RELEASE_TYPE != Hal4Ctxt->sTgtConnectInfo.ReleaseType))
333 {
334 Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
335 /*Update Status*/
336 SendStatus = (NFCSTATUS)(NFC_INVALID_RELEASE_TYPE !=
337 Hal4Ctxt->sTgtConnectInfo.ReleaseType?NFCSTATUS_RELEASED:SendStatus);
338 /*Callback For Target Send*/
339 if(NULL != Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb)
340 {
341 pUpperSendCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb;
342 Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb = NULL;
343 (*pUpperSendCb)(
344 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
345 SendStatus
346 );
347 }
348 else/*Callback For Initiator Send*/
349 {
350 if(NULL != Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb)
351 {
352 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length = 0;
353 pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb;
354 Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL;
355 (*pUpperTrcvCb)(
356 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
357 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
358 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData,
359 SendStatus
360 );
361 }
362 }
363 /*Issue Pending disconnect from HAl4*/
364 if(NFC_INVALID_RELEASE_TYPE != Hal4Ctxt->sTgtConnectInfo.ReleaseType)
365 {
366 SendStatus = phHal4Nfc_Disconnect_Execute(gpphHal4Nfc_Hwref);
367 if((NFCSTATUS_PENDING != SendStatus) &&
368 (NULL != Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb))
369 {
370 pUpperDisconnectCb =
371 Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb;
372 Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb = NULL;
373 (*pUpperDisconnectCb)(
374 Hal4Ctxt->sUpperLayerInfo.psUpperLayerDisconnectCtxt,
375 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
376 SendStatus
377 );/*Notify disconnect failed to upper layer*/
378 }
379 }
380 }
381 else
382 {
383 /*More info remaining in send buffer.continue with sending remaining
384 bytes*/
385 if(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length
386 > Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength)
387 {
388 /*Set more info*/
389 Hal4Ctxt->psTrcvCtxtInfo->
390 XchangeInfo.params.nfc_info.more_info = TRUE;
391 /*copy to tx_buffer ,remaining bytes.NumberOfBytesSent is the
392 number of bytes already sent from current send buffer.*/
393 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer
394 = (Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer
395 + Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent);
396 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length
397 = Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength;
398 Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent
399 += Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength;
400 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length
401 -= Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength;
402 PHDBG_INFO("Hal4:Calling Hci_senddata() from sendcompletehandler1");
403 SendStatus = phHciNfc_Send_Data (
404 Hal4Ctxt->psHciHandle,
405 gpphHal4Nfc_Hwref,
406 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
407 &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo)
408 );
409 if(NFCSTATUS_PENDING == SendStatus)
410 {
411 Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress = TRUE;
412 }
413 }
414 /*Remaining bytes is less than PH_HAL4NFC_MAX_SEND_LEN*/
415 else if(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length > 0)
416 {
417 Hal4Ctxt->psTrcvCtxtInfo->
418 XchangeInfo.params.nfc_info.more_info = FALSE;
419 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length
420 = (uint8_t)Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length;
421 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer
422 = (Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer
423 + Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent);
424 Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent = 0;
425 /*No of bytes remaining for next send*/
426 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length = 0;
427 PHDBG_INFO("Hal4:Calling Hci_senddata() from sendcompletehandler2");
428 SendStatus = phHciNfc_Send_Data (
429 Hal4Ctxt->psHciHandle,
430 gpphHal4Nfc_Hwref,
431 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
432 &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo)
433 );
434 }
435 else/*No more Bytes left.Send complete*/
436 {
437 Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent = 0;
438 /*Callback For Target Send*/
439 if(NULL != Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb)
440 {
441 pUpperSendCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb;
442 Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb = NULL;
443 (*pUpperSendCb)(
444 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
445 SendStatus
446 );
447 }
448 else
449 {
450 /**Start timer to keep track of transceive timeout*/
451 #ifdef TRANSACTION_TIMER
452 phOsalNfc_Timer_Start(
453 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId,
454 PH_HAL4NFC_TRANSCEIVE_TIMEOUT,
455 phHal4Nfc_TrcvTimeoutHandler
456 );
457 #endif /*TRANSACTION_TIMER*/
458 }
459 }
460 }
461 return;
462 }
463
464 /**Receive complete handler*/
phHal4Nfc_RecvCompleteHandler(phHal4Nfc_Hal4Ctxt_t * Hal4Ctxt,void * pInfo)465 void phHal4Nfc_RecvCompleteHandler(phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,void *pInfo)
466 {
467 pphHal4Nfc_ReceiveCallback_t pUpperRecvCb = NULL;
468 pphHal4Nfc_TransceiveCallback_t pUpperTrcvCb = NULL;
469 NFCSTATUS RecvStatus = ((phNfc_sTransactionInfo_t *)pInfo)->status;
470 /*allocate TrcvContext if not already allocated.Required since
471 Receive complete can occur before any other send /receive calls.*/
472 if(NULL == Hal4Ctxt->psTrcvCtxtInfo)
473 {
474 Hal4Ctxt->psTrcvCtxtInfo= (pphHal4Nfc_TrcvCtxtInfo_t)
475 phOsalNfc_GetMemory((uint32_t)
476 (sizeof(phHal4Nfc_TrcvCtxtInfo_t)));
477 if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
478 {
479 (void)memset(Hal4Ctxt->psTrcvCtxtInfo,0,
480 sizeof(phHal4Nfc_TrcvCtxtInfo_t));
481 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
482 = PH_OSALNFC_INVALID_TIMER_ID;
483 Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus
484 = NFCSTATUS_PENDING;
485 }
486 }
487 if(NULL == Hal4Ctxt->psTrcvCtxtInfo)
488 {
489 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
490 RecvStatus = PHNFCSTVAL(CID_NFC_HAL ,
491 NFCSTATUS_INSUFFICIENT_RESOURCES);
492 }
493 else
494 {
495 /*Allocate 4K buffer to copy the received data into*/
496 if(NULL == Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer)
497 {
498 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer
499 = (uint8_t *)phOsalNfc_GetMemory(
500 PH_HAL4NFC_MAX_RECEIVE_BUFFER
501 );
502 if(NULL == Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer)
503 {
504 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,
505 0);
506 RecvStatus = NFCSTATUS_INSUFFICIENT_RESOURCES;
507 }
508 else/*memset*/
509 {
510 (void)memset(
511 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer,
512 0,
513 PH_HAL4NFC_MAX_RECEIVE_BUFFER
514 );
515 }
516 }
517
518 if(RecvStatus != NFCSTATUS_INSUFFICIENT_RESOURCES)
519 {
520 /*Copy the data*/
521 (void)memcpy(
522 (Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer
523 + Hal4Ctxt->psTrcvCtxtInfo->P2PRecvLength),
524 ((phNfc_sTransactionInfo_t *)pInfo)->buffer,
525 ((phNfc_sTransactionInfo_t *)pInfo)->length
526 );
527 /*Update P2PRecvLength,this also acts as the offset to append more
528 received bytes*/
529 Hal4Ctxt->psTrcvCtxtInfo->P2PRecvLength
530 += ((phNfc_sTransactionInfo_t *)pInfo)->length;
531 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length
532 = Hal4Ctxt->psTrcvCtxtInfo->P2PRecvLength;
533 }
534
535 if(RecvStatus != NFCSTATUS_MORE_INFORMATION)
536 {
537 Hal4Ctxt->psTrcvCtxtInfo->P2PRecvLength = 0;
538 Hal4Ctxt->Hal4NextState = (eHal4StateTransaction
539 == Hal4Ctxt->Hal4NextState?eHal4StateInvalid:Hal4Ctxt->Hal4NextState);
540 if(NFCSTATUS_PENDING == Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus)
541 {
542 /*Initiator case*/
543 if(NULL != Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb)
544 {
545 RecvStatus =(NFCSTATUS_RF_TIMEOUT == RecvStatus?
546 NFCSTATUS_DESELECTED:RecvStatus);
547 pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb;
548 Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL;
549 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData
550 = &(Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData);
551 (*pUpperTrcvCb)(
552 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
553 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
554 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData,
555 RecvStatus
556 );
557 }
558 /*P2P target*/
559 else if(NULL != Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb)
560 {
561 pUpperRecvCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb;
562 Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb = NULL;
563 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData
564 = &(Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData);
565 (*pUpperRecvCb)(
566 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
567 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData,
568 RecvStatus
569 );
570 }
571 else
572 {
573 /*Receive data buffer is complete with data & P2P receive has
574 not yet been called*/
575 Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus
576 = NFCSTATUS_SUCCESS;
577 }
578 }
579 }
580 }
581 return;
582 }
583
584 /*Activation complete handler*/
phHal4Nfc_P2PActivateComplete(phHal4Nfc_Hal4Ctxt_t * Hal4Ctxt,void * pInfo)585 void phHal4Nfc_P2PActivateComplete(
586 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,
587 void *pInfo
588 )
589 {
590 phHal_sEventInfo_t *psEventInfo = (phHal_sEventInfo_t *)pInfo;
591 NFCSTATUS Status = NFCSTATUS_SUCCESS;
592 static phHal4Nfc_DiscoveryInfo_t sDiscoveryInfo;
593 /*Copy notification info to provide to upper layer*/
594 phHal4Nfc_NotificationInfo_t uNotificationInfo = {&sDiscoveryInfo};
595 Hal4Ctxt->sTgtConnectInfo.EmulationState = NFC_EVT_ACTIVATED;
596 /*if P2p notification is registered*/
597 if( NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)
598 {
599 /*Allocate remote device Info for P2P target*/
600 uNotificationInfo.psDiscoveryInfo->NumberOfDevices = 1;
601 if(NULL == Hal4Ctxt->rem_dev_list[0])
602 {
603 Hal4Ctxt->rem_dev_list[0]
604 = (phHal_sRemoteDevInformation_t *)
605 phOsalNfc_GetMemory(
606 sizeof(phHal_sRemoteDevInformation_t)
607 );
608 }
609 if(NULL == Hal4Ctxt->rem_dev_list[0])
610 {
611 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
612 Status = PHNFCSTVAL(CID_NFC_HAL ,
613 NFCSTATUS_INSUFFICIENT_RESOURCES);
614 }
615 else
616 {
617 (void)memset((void *)Hal4Ctxt->rem_dev_list[0],
618 0,sizeof(phHal_sRemoteDevInformation_t));
619 /*Copy device info*/
620 (void)memcpy(Hal4Ctxt->rem_dev_list[0],
621 psEventInfo->eventInfo.pRemoteDevInfo,
622 sizeof(phHal_sRemoteDevInformation_t)
623 );
624 /*Allocate Trcv context info*/
625 if(NULL == Hal4Ctxt->psTrcvCtxtInfo)
626 {
627 Hal4Ctxt->psTrcvCtxtInfo= (pphHal4Nfc_TrcvCtxtInfo_t)
628 phOsalNfc_GetMemory((uint32_t)
629 (sizeof(phHal4Nfc_TrcvCtxtInfo_t)));
630 if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
631 {
632 (void)memset(Hal4Ctxt->psTrcvCtxtInfo,0,
633 sizeof(phHal4Nfc_TrcvCtxtInfo_t));
634 Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus
635 = NFCSTATUS_PENDING;
636 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
637 = PH_OSALNFC_INVALID_TIMER_ID;
638 }
639 }
640 if(NULL == Hal4Ctxt->psTrcvCtxtInfo)
641 {
642 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
643 Status= PHNFCSTVAL(CID_NFC_HAL ,
644 NFCSTATUS_INSUFFICIENT_RESOURCES);
645 }
646 else
647 {
648 /*Update state*/
649 Hal4Ctxt->Hal4CurrentState = eHal4StateEmulation;
650 Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
651 uNotificationInfo.psDiscoveryInfo->ppRemoteDevInfo
652 = Hal4Ctxt->rem_dev_list;
653 /*set session Opened ,this will keep track of whether the session
654 is alive.will be reset if a Event DEACTIVATED is received*/
655 Hal4Ctxt->rem_dev_list[0]->SessionOpened = TRUE;
656 (*Hal4Ctxt->sUpperLayerInfo.pP2PNotification)(
657 Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt,
658 NFC_DISCOVERY_NOTIFICATION,
659 uNotificationInfo,
660 Status
661 );
662 }
663 }
664 }
665 return;
666 }
667
668 /*Deactivation complete handler*/
phHal4Nfc_HandleP2PDeActivate(phHal4Nfc_Hal4Ctxt_t * Hal4Ctxt,void * pInfo)669 void phHal4Nfc_HandleP2PDeActivate(
670 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,
671 void *pInfo
672 )
673 {
674 pphHal4Nfc_ReceiveCallback_t pUpperRecvCb = NULL;
675 pphHal4Nfc_SendCallback_t pUpperSendCb = NULL;
676 phHal4Nfc_NotificationInfo_t uNotificationInfo;
677 uNotificationInfo.psEventInfo = (phHal_sEventInfo_t *)pInfo;
678 /*session is closed*/
679 if(NULL != Hal4Ctxt->rem_dev_list[0])
680 {
681 Hal4Ctxt->rem_dev_list[0]->SessionOpened = FALSE;
682 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
683 }
684 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice = NULL;
685 /*Update state*/
686 Hal4Ctxt->Hal4CurrentState = eHal4StateOpenAndReady;
687 Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
688 Hal4Ctxt->sTgtConnectInfo.EmulationState = NFC_EVT_DEACTIVATED;
689 /*If Trcv ctxt info is allocated ,free it here*/
690 if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
691 {
692 if(PH_OSALNFC_INVALID_TIMER_ID !=
693 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId)
694 {
695 phOsalNfc_Timer_Stop(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId);
696 phOsalNfc_Timer_Delete(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId);
697 }
698 pUpperRecvCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb;
699 pUpperSendCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb;
700 /*Free Hal4 resources used by Target*/
701 if (NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer)
702 {
703 phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo->
704 sLowerRecvData.buffer);
705 }
706 if((NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
707 && (NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData))
708 {
709 phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData);
710 }
711 phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo);
712 Hal4Ctxt->psTrcvCtxtInfo = NULL;
713 }
714 /*if recv callback is pending*/
715 if(NULL != pUpperRecvCb)
716 {
717 (*pUpperRecvCb)(
718 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
719 NULL,
720 NFCSTATUS_DESELECTED
721 );
722 }
723 /*if send callback is pending*/
724 else if(NULL != pUpperSendCb)
725 {
726 (*pUpperSendCb)(
727 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
728 NFCSTATUS_DESELECTED
729 );
730 }
731 /*if pP2PNotification is registered*/
732 else if(NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)
733 {
734 (*Hal4Ctxt->sUpperLayerInfo.pP2PNotification)(
735 Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt,
736 NFC_EVENT_NOTIFICATION,
737 uNotificationInfo,
738 NFCSTATUS_DESELECTED
739 );
740 }
741 else/*Call Default event handler*/
742 {
743 if(NULL != Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler)
744 {
745 Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler(
746 Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt,
747 NFC_EVENT_NOTIFICATION,
748 uNotificationInfo,
749 NFCSTATUS_DESELECTED
750 );
751 }
752 }
753 }
754