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*/
52static 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.*/
59NFCSTATUS
60phHal4Nfc_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
182NFCSTATUS
183phHal4Nfc_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().*/
284static 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*/
323void 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*/
465void 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*/
585void 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*/
669void 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