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