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