Home | History | Annotate | Download | only in src
      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_MORE_INFORMATION;
    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 }
    751