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_Reader.c
     18 * \brief Hal4Nfc Reader source.
     19 *
     20 * Project: NFC-FRI 1.1
     21 *
     22 * $Date: Mon May 31 11:43:43 2010 $
     23 * $Author: ing07385 $
     24 * $Revision: 1.120 $
     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 <phHciNfc.h>
     34 #include <phOsalNfc_Timer.h>
     35 #include <phNfcConfig.h>
     36 
     37 
     38 /* ------------------------------- Macros ------------------------------------*/
     39 #define PH_HAL4NFC_CMD_LENGTH      PHHAL_MAX_DATASIZE+12/**< Cmd length used
     40                                                               for Transceive*/
     41 #define PH_HAL4NFC_MAX_TRCV_LEN                     4096 /**<Only a max of 1KB
     42                                                               can be sent at
     43                                                               a time*/
     44 #define PH_HAL4NFC_FLAG_0                              0
     45 
     46 #define PH_HAL4NFC_FLAG_1                              1
     47 
     48 #define PH_HAL4NFC_SEL_SECTOR1_BYTE0                0xC2
     49 #define PH_HAL4NFC_SEL_SECTOR1_BYTE1                0xFF
     50 
     51 #define PH_HAL4NFC_SEL_SECTOR2_BYTE0                0x02
     52 #define PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED        0x00
     53 
     54 
     55 /* --------------------Structures and enumerations --------------------------*/
     56 
     57 static void phHal4Nfc_Iso_3A_Transceive(
     58                         phHal_sTransceiveInfo_t   *psTransceiveInfo,
     59                         phHal4Nfc_Hal4Ctxt_t      *Hal4Ctxt
     60                         );
     61 
     62 static void phHal4Nfc_MifareTransceive(
     63                         phHal_sTransceiveInfo_t   *psTransceiveInfo,
     64                         phHal_sRemoteDevInformation_t  *psRemoteDevInfo,
     65                         phHal4Nfc_Hal4Ctxt_t      *Hal4Ctxt
     66                         );
     67 
     68 /*Allows to connect to a single, specific, already known Remote Device.*/
     69 NFCSTATUS phHal4Nfc_Connect(
     70                             phHal_sHwReference_t          *psHwReference,
     71                             phHal_sRemoteDevInformation_t *psRemoteDevInfo,
     72                             pphHal4Nfc_ConnectCallback_t   pNotifyConnectCb,
     73                             void                          *pContext
     74                             )
     75 {
     76     NFCSTATUS RetStatus = NFCSTATUS_SUCCESS;
     77     phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
     78     uint8_t RemoteDevCount = 0;
     79     int32_t MemCmpRet = 0;
     80     /*NULL chks*/
     81     if(NULL == psHwReference
     82         || NULL == pNotifyConnectCb
     83         || NULL == psRemoteDevInfo)
     84     {
     85         phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
     86         RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
     87     }
     88     /*Check initialised state*/
     89     else if((NULL == psHwReference->hal_context)
     90                         || (((phHal4Nfc_Hal4Ctxt_t *)
     91                                 psHwReference->hal_context)->Hal4CurrentState
     92                                                < eHal4StateOpenAndReady)
     93                         || (((phHal4Nfc_Hal4Ctxt_t *)
     94                                 psHwReference->hal_context)->Hal4NextState
     95                                                == eHal4StateClosed))
     96     {
     97         RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED);
     98     }
     99     else if ((psRemoteDevInfo ==
    100              ((phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context)->
    101                 sTgtConnectInfo.psConnectedDevice)
    102              &&((phHal_eNfcIP1_Target == psRemoteDevInfo->RemDevType)
    103                 ||(phHal_eJewel_PICC == psRemoteDevInfo->RemDevType)))
    104     {
    105         RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_FEATURE_NOT_SUPPORTED);
    106     }
    107     else
    108     {
    109         /*Get Hal ctxt from hardware reference*/
    110         Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
    111         /*Register upper layer context*/
    112         Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
    113         /*Register upper layer callback*/
    114         Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = pNotifyConnectCb;
    115         /*Allow Connect only if no other remote device is connected*/
    116         if((eHal4StateTargetDiscovered == Hal4Ctxt->Hal4CurrentState)
    117             && (NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice))
    118         {
    119             RemoteDevCount = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
    120             while(0 != RemoteDevCount)
    121             {
    122                 RemoteDevCount--;
    123                 /*Check if handle provided by upper layer matches with any
    124                   remote device in the list*/
    125                 if(psRemoteDevInfo
    126                     == (Hal4Ctxt->rem_dev_list[RemoteDevCount]))
    127                 {
    128 
    129                     Hal4Ctxt->sTgtConnectInfo.psConnectedDevice
    130                                   = Hal4Ctxt->rem_dev_list[RemoteDevCount];
    131                     break;
    132                 }
    133             }/*End of while*/
    134 
    135             if(NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
    136             {
    137                 /*No matching device handle in list*/
    138                 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,
    139                                         NFCSTATUS_INVALID_REMOTE_DEVICE);
    140             }
    141             else
    142             {
    143                 MemCmpRet = phOsalNfc_MemCompare(
    144                     (void *)&(psRemoteDevInfo->RemoteDevInfo),
    145                     (void *)&(Hal4Ctxt->rem_dev_list[Hal4Ctxt
    146                     ->psADDCtxtInfo->nbr_of_devices - 1]->RemoteDevInfo),
    147                     sizeof(phHal_uRemoteDevInfo_t));
    148 
    149                 /*If device is already selected issue connect from here*/
    150                 if(0 == MemCmpRet)
    151                 {
    152                     RetStatus = phHciNfc_Connect(Hal4Ctxt->psHciHandle,
    153                         (void *)psHwReference,
    154                         Hal4Ctxt->rem_dev_list[RemoteDevCount]);
    155                     if(NFCSTATUS_PENDING == RetStatus)
    156                     {
    157                         Hal4Ctxt->Hal4NextState = eHal4StateTargetConnected;
    158                     }
    159 
    160                 }
    161                 else/*Select the matching device to connect to*/
    162                 {
    163                     RetStatus = phHciNfc_Reactivate (
    164                         Hal4Ctxt->psHciHandle,
    165                         (void *)psHwReference,
    166                         Hal4Ctxt->rem_dev_list[RemoteDevCount]
    167                         );
    168                     Hal4Ctxt->Hal4NextState = eHal4StateTargetActivate;
    169                 }
    170                 if(NFCSTATUS_PENDING != RetStatus)
    171                 {
    172                     /*Rollback state*/
    173                     Hal4Ctxt->Hal4CurrentState = eHal4StateOpenAndReady;
    174                     Hal4Ctxt->sTgtConnectInfo.psConnectedDevice =  NULL;
    175                     Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = NULL;
    176                     Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL;
    177                 }
    178             }
    179         }
    180         /*Issue Reconnect*/
    181         else if(psRemoteDevInfo ==
    182                     Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
    183         {
    184             RetStatus = phHciNfc_Reactivate (
    185                 Hal4Ctxt->psHciHandle,
    186                 (void *)psHwReference,
    187                 psRemoteDevInfo
    188                 );
    189                 Hal4Ctxt->Hal4NextState = eHal4StateTargetActivate;
    190         }
    191         else if(NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
    192         {
    193             /*Wrong state to issue connect*/
    194             RetStatus = PHNFCSTVAL(CID_NFC_HAL,
    195                                     NFCSTATUS_INVALID_REMOTE_DEVICE);
    196         }
    197         else/*No Target or already connected to device*/
    198         {
    199             RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_FAILED);
    200         }
    201 
    202     }
    203     return RetStatus;
    204 }
    205 
    206 /*For Ordering Transceive Info for ISO_3A type tags*/
    207 static void phHal4Nfc_Iso_3A_Transceive(
    208                         phHal_sTransceiveInfo_t   *psTransceiveInfo,
    209                         phHal4Nfc_Hal4Ctxt_t      *Hal4Ctxt
    210                         )
    211 {
    212     uint16_t i;
    213     uint16_t counter= 0;
    214     /* Mifare UL, Keep MIFARE RAW command as it is */
    215     Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type
    216                     = (uint8_t)psTransceiveInfo->cmd.MfCmd;
    217     /* Set flags for Select Sector */
    218     if (psTransceiveInfo->sSendData.buffer[0] != phHal_eMifareWrite4)
    219     {
    220         if (Hal4Ctxt->SelectSectorFlag == PH_HAL4NFC_FLAG_0)
    221         {
    222             /* First Select Sector command */
    223             if ((psTransceiveInfo->sSendData.buffer[1] == PH_HAL4NFC_SEL_SECTOR1_BYTE0) &&
    224                 (psTransceiveInfo->sSendData.buffer[2] == PH_HAL4NFC_SEL_SECTOR1_BYTE1))
    225             {
    226                 Hal4Ctxt->SelectSectorFlag++;
    227                 PHDBG_INFO("Inside 3ATrancv,first cmd, SelectSectorFlag is 1");
    228                 for (i = 1; i < psTransceiveInfo->sSendData.length; i++)
    229                 {
    230                     psTransceiveInfo->sSendData.buffer[i - 1] =
    231                         psTransceiveInfo->sSendData.buffer[i];
    232                 }
    233 
    234                 psTransceiveInfo->sSendData.length--;
    235             }
    236             else
    237             {
    238                 PHDBG_INFO("Inside 3ATrancv,first cmd,setting SelectSectorFlag 0");
    239                 Hal4Ctxt->SelectSectorFlag = 0;
    240             }
    241         }
    242         else if (Hal4Ctxt->SelectSectorFlag == PH_HAL4NFC_FLAG_1)
    243         {
    244             if ((psTransceiveInfo->sSendData.buffer[1] < PH_HAL4NFC_SEL_SECTOR2_BYTE0) &&
    245                 (psTransceiveInfo->sSendData.buffer[2] == PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED) &&
    246                 (psTransceiveInfo->sSendData.buffer[3] == PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED) &&
    247                 (psTransceiveInfo->sSendData.buffer[4] == PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED))
    248             {
    249                 Hal4Ctxt->SelectSectorFlag++;
    250                 PHDBG_INFO("Inside 3ATrancv,2nd cmd, SelectSectorFlag set to 2");
    251                 for (i = 1; i < psTransceiveInfo->sSendData.length; i++)
    252                 {
    253                     psTransceiveInfo->sSendData.buffer[i - 1] =
    254                         psTransceiveInfo->sSendData.buffer[i];
    255                 }
    256 
    257                 psTransceiveInfo->sSendData.length--;
    258             }
    259             else
    260             {
    261                 PHDBG_INFO("Inside 3ATrancv,2nd cmd, SelectSectorFlag set to 0");
    262                 Hal4Ctxt->SelectSectorFlag = 0;
    263             }
    264         }
    265         else
    266         {
    267             Hal4Ctxt->SelectSectorFlag = 0;
    268         }
    269     }
    270     else
    271     {
    272         PHDBG_INFO("Inside 3ATrancv,Mifarewrite4");
    273         /* Convert MIFARE RAW to MIFARE CMD */
    274         if (psTransceiveInfo->cmd.MfCmd == phHal_eMifareRaw)
    275         {
    276             psTransceiveInfo->cmd.MfCmd =
    277                 (phHal_eMifareCmdList_t)psTransceiveInfo->sSendData.buffer[0];
    278 
    279             Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type =
    280                 (uint8_t)psTransceiveInfo->cmd.MfCmd;
    281 
    282             Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.addr =
    283                 psTransceiveInfo->addr =
    284                 psTransceiveInfo->sSendData.buffer[1];
    285 
    286             for (counter = 2; counter < psTransceiveInfo->sSendData.length;
    287                  counter++)
    288             {
    289                 psTransceiveInfo->sSendData.buffer[counter - 2] =
    290                     psTransceiveInfo->sSendData.buffer[counter];
    291             }
    292             PHDBG_INFO("Hal4:Inside 3A_Trcv() ,minus length by 4");
    293             psTransceiveInfo->sSendData.length =
    294                 psTransceiveInfo->sSendData.length - 4;
    295         }
    296         else
    297         {
    298             Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type
    299                         = (uint8_t)psTransceiveInfo->cmd.MfCmd;
    300         }
    301     }
    302     return;
    303 }
    304 
    305 /*For Ordering Transceive Info for Mifare tags*/
    306 static void phHal4Nfc_MifareTransceive(
    307                         phHal_sTransceiveInfo_t   *psTransceiveInfo,
    308                         phHal_sRemoteDevInformation_t  *psRemoteDevInfo,
    309                         phHal4Nfc_Hal4Ctxt_t      *Hal4Ctxt
    310                         )
    311 {
    312     uint16_t counter;
    313     if (
    314 #ifndef DISABLE_MIFARE_UL_WRITE_WORKAROUND
    315         phHal_eMifareWrite4 != psTransceiveInfo->sSendData.buffer[0]
    316 #else
    317         1
    318 #endif/*#ifndef DISABLE_MIFARE_UL_WRITE_WORKAROUND*/
    319         )
    320 
    321     {
    322         /* Mifare UL, Keep MIFARE RAW command as it is */
    323         Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type
    324                         = (uint8_t)psTransceiveInfo->cmd.MfCmd;
    325 
    326     }
    327     else
    328     {
    329         /* Convert MIFARE RAW to MIFARE CMD */
    330         if (psTransceiveInfo->cmd.MfCmd == phHal_eMifareRaw)
    331         {
    332             psTransceiveInfo->cmd.MfCmd =
    333                 (phHal_eMifareCmdList_t)psTransceiveInfo->sSendData.buffer[0];
    334 
    335             Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type =
    336                 (uint8_t)psTransceiveInfo->cmd.MfCmd;
    337 
    338             Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.addr =
    339                 psTransceiveInfo->addr =
    340                 psTransceiveInfo->sSendData.buffer[1];
    341 
    342             for (counter = 2; counter < psTransceiveInfo->sSendData.length;
    343                  counter++)
    344             {
    345                 psTransceiveInfo->sSendData.buffer[counter - 2] =
    346                     psTransceiveInfo->sSendData.buffer[counter];
    347             }
    348             PHDBG_INFO("Hal4:Inside MifareTrcv() ,minus length by 4");
    349             psTransceiveInfo->sSendData.length =
    350                 psTransceiveInfo->sSendData.length - 4;
    351 
    352         }
    353         else
    354         {
    355             Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type
    356                         = (uint8_t)psTransceiveInfo->cmd.MfCmd;
    357         }
    358     }
    359     return;
    360 }
    361 
    362 /*  The phHal4Nfc_Transceive function allows the Initiator to send and receive
    363  *  data to and from the Remote Device selected by the caller.*/
    364 NFCSTATUS phHal4Nfc_Transceive(
    365                                phHal_sHwReference_t          *psHwReference,
    366                                phHal_sTransceiveInfo_t       *psTransceiveInfo,
    367                                phHal_sRemoteDevInformation_t  *psRemoteDevInfo,
    368                                pphHal4Nfc_TransceiveCallback_t pTrcvCallback,
    369                                void                           *pContext
    370                                )
    371 {
    372     NFCSTATUS RetStatus = NFCSTATUS_PENDING;
    373     phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)pContext;
    374 
    375     /*NULL checks*/
    376     if((NULL == psHwReference)
    377         ||( NULL == pTrcvCallback )
    378         || (NULL == psRemoteDevInfo)
    379         || (NULL == psTransceiveInfo)
    380         || (NULL == psTransceiveInfo->sRecvData.buffer)
    381         || (NULL == psTransceiveInfo->sSendData.buffer)
    382         )
    383     {
    384         phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
    385         RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
    386     }
    387 #ifdef HAL_TRCV_LIMIT
    388     else if(PH_HAL4NFC_MAX_TRCV_LEN < psTransceiveInfo->sSendData.length)
    389     {
    390         RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_ALLOWED);
    391     }
    392 #endif/*#ifdef HAL_TRCV_LIMIT*/
    393     /*Check initialised state*/
    394     else if((NULL == psHwReference->hal_context)
    395                         || (((phHal4Nfc_Hal4Ctxt_t *)
    396                                 psHwReference->hal_context)->Hal4CurrentState
    397                                                < eHal4StateOpenAndReady)
    398                         || (((phHal4Nfc_Hal4Ctxt_t *)
    399                                 psHwReference->hal_context)->Hal4NextState
    400                                                == eHal4StateClosed))
    401     {
    402         RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED);
    403     }
    404     else
    405     {
    406         Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
    407         gpphHal4Nfc_Hwref = (phHal_sHwReference_t *)psHwReference;
    408         if((eHal4StateTargetConnected != Hal4Ctxt->Hal4CurrentState)
    409             ||(eHal4StateInvalid != Hal4Ctxt->Hal4NextState))
    410         {
    411             /*Hal4 state Busy*/
    412             RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_BUSY);
    413             PHDBG_INFO("HAL4:Trcv Failed.Returning Busy");
    414         }
    415         else if(psRemoteDevInfo != Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
    416         {
    417             /*No such Target connected*/
    418             RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_INVALID_REMOTE_DEVICE);
    419         }
    420         else
    421         {
    422             /*allocate Trcv context*/
    423             if(NULL == Hal4Ctxt->psTrcvCtxtInfo)
    424             {
    425                 Hal4Ctxt->psTrcvCtxtInfo= (pphHal4Nfc_TrcvCtxtInfo_t)
    426                 phOsalNfc_GetMemory((uint32_t)(sizeof(phHal4Nfc_TrcvCtxtInfo_t)));
    427                 if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
    428                 {
    429                     (void)memset(Hal4Ctxt->psTrcvCtxtInfo,0,
    430                                         sizeof(phHal4Nfc_TrcvCtxtInfo_t));
    431                     Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus
    432                         = NFCSTATUS_PENDING;
    433                     Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
    434                                                 = PH_OSALNFC_INVALID_TIMER_ID;
    435                 }
    436             }
    437             if(NULL == Hal4Ctxt->psTrcvCtxtInfo)
    438             {
    439                 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
    440                 RetStatus= PHNFCSTVAL(CID_NFC_HAL ,
    441                                             NFCSTATUS_INSUFFICIENT_RESOURCES);
    442             }
    443             else
    444             {
    445                 /*Process transceive based on Remote device type*/
    446                 switch(Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemDevType)
    447                 {
    448                 case phHal_eISO14443_3A_PICC:
    449                     phHal4Nfc_Iso_3A_Transceive(
    450                                         psTransceiveInfo,
    451                                         Hal4Ctxt
    452                                         );
    453                     break;
    454                 case phHal_eMifare_PICC:
    455                     PHDBG_INFO("Mifare Cmd received");
    456                     phHal4Nfc_MifareTransceive(
    457                                         psTransceiveInfo,
    458                                         psRemoteDevInfo,
    459                                         Hal4Ctxt
    460                                         );
    461 
    462 #if 0
    463                     Hal4Ctxt->psTrcvCtxtInfo->
    464                         XchangeInfo.params.tag_info.cmd_type
    465                                         = (uint8_t)psTransceiveInfo->cmd.MfCmd;
    466 #endif
    467                     break;
    468                 case phHal_eISO14443_A_PICC:
    469                 case phHal_eISO14443_B_PICC:
    470                     PHDBG_INFO("ISO14443 Cmd received");
    471                     Hal4Ctxt->psTrcvCtxtInfo->
    472                         XchangeInfo.params.tag_info.cmd_type
    473                             = (uint8_t)psTransceiveInfo->cmd.Iso144434Cmd;
    474                     break;
    475                 case phHal_eISO15693_PICC:
    476                     PHDBG_INFO("ISO15693 Cmd received");
    477                     Hal4Ctxt->psTrcvCtxtInfo->
    478                         XchangeInfo.params.tag_info.cmd_type
    479                             = (uint8_t)psTransceiveInfo->cmd.Iso15693Cmd;
    480                     break;
    481                 case phHal_eNfcIP1_Target:
    482                     {
    483                         PHDBG_INFO("NfcIP1 Transceive");
    484                         Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData
    485                             = &(psTransceiveInfo->sSendData);
    486                         Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData =
    487                             &(psTransceiveInfo->sRecvData);
    488                     }
    489                     break;
    490                 case phHal_eFelica_PICC:
    491                     PHDBG_INFO("Felica Cmd received");
    492                     Hal4Ctxt->psTrcvCtxtInfo->
    493                         XchangeInfo.params.tag_info.cmd_type
    494                         = (uint8_t)psTransceiveInfo->cmd.FelCmd;
    495                     break;
    496                 case phHal_eJewel_PICC:
    497                     PHDBG_INFO("Jewel Cmd received");
    498                     Hal4Ctxt->psTrcvCtxtInfo->
    499                         XchangeInfo.params.tag_info.cmd_type
    500                         = (uint8_t)psTransceiveInfo->cmd.JewelCmd;
    501                     break;
    502                 case phHal_eISO14443_BPrime_PICC:
    503                     RetStatus = PHNFCSTVAL(CID_NFC_HAL ,
    504                                               NFCSTATUS_FEATURE_NOT_SUPPORTED);
    505                     break;
    506                 default:
    507                     PHDBG_WARNING("Invalid Device type received");
    508                     RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_FAILED);
    509                     break;
    510 
    511                 }
    512             }
    513         }
    514         /*If status is anything other than NFCSTATUS_PENDING ,an error has
    515           already occured, so dont process any further and return*/
    516         if(RetStatus == NFCSTATUS_PENDING)
    517         {
    518             if(phHal_eNfcIP1_Target ==
    519                   Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemDevType)
    520             {
    521                 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
    522                 /*Register upper layer callback*/
    523                 Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb  = pTrcvCallback;
    524                 if(PH_HAL4NFC_MAX_SEND_LEN
    525                     >= psTransceiveInfo->sSendData.length)
    526                 {
    527                     Hal4Ctxt->psTrcvCtxtInfo->
    528                         XchangeInfo.params.nfc_info.more_info = FALSE;
    529                     Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length
    530                                 = (uint8_t)psTransceiveInfo->sSendData.length;
    531                     Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer
    532                         = psTransceiveInfo->sSendData.buffer;
    533                     /*Number of bytes remaining for next send*/
    534                     Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length = 0;
    535                 }
    536                 else
    537                 {
    538                     Hal4Ctxt->psTrcvCtxtInfo->
    539                         XchangeInfo.params.nfc_info.more_info = TRUE;
    540                     Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer
    541                         = Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer;
    542                     Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length
    543                                                 = PH_HAL4NFC_MAX_SEND_LEN;
    544 #if 0
    545                     Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer
    546                                                 += PH_HAL4NFC_MAX_SEND_LEN;
    547 #else
    548                     Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent
    549                         += PH_HAL4NFC_MAX_SEND_LEN;
    550 #endif
    551                     /*Number of bytes remaining for next send*/
    552                     Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length
    553                                                -= PH_HAL4NFC_MAX_SEND_LEN;
    554                 }
    555                 Hal4Ctxt->Hal4NextState = eHal4StateTransaction;
    556 #ifdef TRANSACTION_TIMER
    557                 /**Create a timer to keep track of transceive timeout*/
    558                 if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
    559                     == PH_OSALNFC_INVALID_TIMER_ID)
    560                 {
    561                     PHDBG_INFO("HAL4: Transaction Timer Create for transceive");
    562                     Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
    563                         = phOsalNfc_Timer_Create();
    564                 }
    565                 if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
    566                     == PH_OSALNFC_INVALID_TIMER_ID)
    567                 {
    568                     RetStatus = PHNFCSTVAL(CID_NFC_HAL ,
    569                         NFCSTATUS_INSUFFICIENT_RESOURCES);
    570                 }
    571                 else
    572 #endif/*TRANSACTION_TIMER*/
    573                 {
    574                     PHDBG_INFO("Hal4:Calling phHciNfc_Send_Data from Hal4_Transceive()");
    575                     RetStatus = phHciNfc_Send_Data (
    576                                     Hal4Ctxt->psHciHandle,
    577                                     psHwReference,
    578                                     Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
    579                                     &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo)
    580                                     );
    581                     if(NFCSTATUS_PENDING == RetStatus)
    582                     {
    583                         Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress = TRUE;
    584                     }
    585                 }
    586             }
    587             else if(psTransceiveInfo->sSendData.length > PH_HAL4NFC_CMD_LENGTH)
    588             {
    589                 RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_INVALID_PARAMETER);
    590             }
    591             else if((psTransceiveInfo->sSendData.length == 0)
    592                     && (Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length != 0))
    593             {
    594                 PHDBG_INFO("Hal4:Read remaining bytes");
    595                 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData
    596                                             = &(psTransceiveInfo->sRecvData);
    597                 /*Number of read bytes left is greater than bytes requested
    598                     by upper layer*/
    599                 if(Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length
    600                     < Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length)
    601                 {
    602                     (void)memcpy(Hal4Ctxt->psTrcvCtxtInfo
    603                                                 ->psUpperRecvData->buffer,
    604                         (Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer
    605                         + Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset)
    606                         ,Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length);
    607                     Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length -=
    608                         Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length;
    609                     Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset
    610                         += Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length;
    611                     RetStatus = PHNFCSTVAL(CID_NFC_HAL ,
    612                                                 NFCSTATUS_MORE_INFORMATION);
    613                 }
    614                 else/*Number of read bytes left is smaller.Copy all bytes
    615                       and free Hal's buffer*/
    616                 {
    617                     Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length
    618                         = Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length;
    619                     (void)memcpy(Hal4Ctxt->psTrcvCtxtInfo
    620                                                         ->psUpperRecvData
    621                                                                     ->buffer,
    622                         (Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer
    623                             + Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset)
    624                         ,Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length);
    625                     phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo
    626                                                     ->sLowerRecvData.buffer);
    627                     Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer = NULL;
    628                     Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length = 0;
    629                     Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset   = 0;
    630                     RetStatus = NFCSTATUS_SUCCESS;
    631                 }
    632             }
    633             else/*No more bytes remaining in Hal.Read from device*/
    634             {
    635                  /*Register upper layer context*/
    636                 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
    637                 /*Register upper layer callback*/
    638                 Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb  = pTrcvCallback;
    639                 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.addr
    640                                                     = psTransceiveInfo->addr;
    641                 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length
    642                                 = (uint8_t)psTransceiveInfo->sSendData.length;
    643                 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer
    644                                         = psTransceiveInfo->sSendData.buffer;
    645                 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData
    646                                             = &(psTransceiveInfo->sRecvData);
    647 #ifdef TRANSACTION_TIMER
    648                 /**Create a timer to keep track of transceive timeout*/
    649                 if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
    650                                     == PH_OSALNFC_INVALID_TIMER_ID)
    651                 {
    652                     PHDBG_INFO("HAL4: Transaction Timer Create for transceive");
    653                     Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
    654                                             = phOsalNfc_Timer_Create();
    655                 }
    656                 if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
    657                     == PH_OSALNFC_INVALID_TIMER_ID)
    658                 {
    659                     RetStatus = PHNFCSTVAL(CID_NFC_HAL ,
    660                                            NFCSTATUS_INSUFFICIENT_RESOURCES);
    661                 }
    662                 else
    663 #endif /*TRANSACTION_TIMER*/
    664                 {
    665                     PHDBG_INFO("Calling phHciNfc_Exchange_Data");
    666                     RetStatus = phHciNfc_Exchange_Data(
    667                         Hal4Ctxt->psHciHandle,
    668                         psHwReference,
    669                         Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
    670                         &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo)
    671                         );
    672 
    673                     if(NFCSTATUS_PENDING == RetStatus)
    674                     {
    675                         Hal4Ctxt->Hal4NextState = eHal4StateTransaction;
    676 #ifdef TRANSACTION_TIMER
    677                         /**Start timer to keep track of transceive timeout*/
    678                         phOsalNfc_Timer_Start(
    679                             Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId,
    680                             PH_HAL4NFC_TRANSCEIVE_TIMEOUT,
    681                             phHal4Nfc_TrcvTimeoutHandler
    682                             );
    683 #endif/*#ifdef TRANSACTION_TIMER*/
    684                     }
    685                     else
    686                     {
    687                         Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
    688                     }
    689                 }
    690             }
    691         }
    692     }
    693     return RetStatus;
    694 }
    695 
    696 #ifdef TRANSACTION_TIMER
    697 /**Handle transceive timeout*/
    698 void phHal4Nfc_TrcvTimeoutHandler(uint32_t TrcvTimerId)
    699 {
    700     phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = gpphHal4Nfc_Hwref->hal_context;
    701     pphHal4Nfc_ReceiveCallback_t pUpperRecvCb = NULL;
    702     pphHal4Nfc_TransceiveCallback_t pUpperTrcvCb = NULL;
    703     phOsalNfc_Timer_Stop(TrcvTimerId);
    704     phOsalNfc_Timer_Delete(TrcvTimerId);
    705     Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId = PH_OSALNFC_INVALID_TIMER_ID;
    706     Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
    707     /*For a P2P target*/
    708     if(Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb != NULL)
    709     {
    710         pUpperRecvCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb;
    711         Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb = NULL;
    712         (*pUpperRecvCb)(
    713             Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
    714             NULL,
    715             NFCSTATUS_RF_TIMEOUT
    716             );
    717     }
    718     else
    719     {
    720         /*For a P2P Initiator and tags*/
    721         if(Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb != NULL)
    722         {
    723             pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb;
    724             Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL;
    725             (*pUpperTrcvCb)(
    726                         Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
    727                         Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
    728                         NULL,
    729                         NFCSTATUS_RF_TIMEOUT
    730                         );
    731         }
    732     }
    733 }
    734 #endif /*TRANSACTION_TIMER*/
    735 
    736 
    737 /**The function allows to disconnect from a specific Remote Device.*/
    738 NFCSTATUS phHal4Nfc_Disconnect(
    739                         phHal_sHwReference_t          *psHwReference,
    740                         phHal_sRemoteDevInformation_t *psRemoteDevInfo,
    741                         phHal_eReleaseType_t           ReleaseType,
    742                         pphHal4Nfc_DiscntCallback_t    pDscntCallback,
    743                         void                             *pContext
    744                         )
    745 {
    746     NFCSTATUS RetStatus = NFCSTATUS_PENDING;
    747     phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
    748     PHDBG_INFO("Hal4:Inside Hal4 disconnect");
    749     /*NULL checks*/
    750     if(NULL == psHwReference || NULL == pDscntCallback
    751         || NULL == psRemoteDevInfo)
    752     {
    753         phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
    754         RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
    755     }
    756     /*Check Initialised state*/
    757     else if((NULL == psHwReference->hal_context)
    758                         || (((phHal4Nfc_Hal4Ctxt_t *)
    759                                 psHwReference->hal_context)->Hal4CurrentState
    760                                                < eHal4StateOpenAndReady)
    761                         || (((phHal4Nfc_Hal4Ctxt_t *)
    762                                 psHwReference->hal_context)->Hal4NextState
    763                                                == eHal4StateClosed))
    764     {
    765         RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED);
    766     }
    767     else if(((phHal4Nfc_Hal4Ctxt_t *)
    768                     psHwReference->hal_context)->Hal4CurrentState
    769                     != eHal4StateTargetConnected)
    770     {
    771         PHDBG_INFO("Hal4:Current sate is not connect.Release returning failed");
    772         RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_FAILED);
    773     }
    774     else
    775     {
    776         Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
    777         if((Hal4Ctxt->sTgtConnectInfo.psConnectedDevice == NULL)
    778             || (psRemoteDevInfo != Hal4Ctxt->sTgtConnectInfo.psConnectedDevice))
    779         {
    780             PHDBG_INFO("Hal4:disconnect returning INVALID_REMOTE_DEVICE");
    781             RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_INVALID_REMOTE_DEVICE);
    782         }
    783         else
    784         {
    785             /*Register upper layer context*/
    786             Hal4Ctxt->sUpperLayerInfo.psUpperLayerDisconnectCtxt = pContext;
    787             /*Register upper layer callback*/
    788             Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb  = pDscntCallback;
    789             /*Register Release Type*/
    790             Hal4Ctxt->sTgtConnectInfo.ReleaseType = ReleaseType;
    791             if((eHal4StateTransaction == Hal4Ctxt->Hal4NextState)
    792                 &&((phHal_eNfcIP1_Target != psRemoteDevInfo->RemDevType)
    793                 ||((NFC_DISCOVERY_CONTINUE != ReleaseType)
    794                    &&(NFC_DISCOVERY_RESTART != ReleaseType))))
    795             {
    796                 Hal4Ctxt->sTgtConnectInfo.ReleaseType
    797                                                   = NFC_INVALID_RELEASE_TYPE;
    798                 PHDBG_INFO("Hal4:disconnect returning NFCSTATUS_NOT_ALLOWED");
    799                 RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_NOT_ALLOWED);
    800             }
    801             else if((eHal4StateTransaction == Hal4Ctxt->Hal4NextState)
    802                     &&(NULL != Hal4Ctxt->psTrcvCtxtInfo)
    803                     &&(TRUE == Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress))
    804             {
    805                 /*store the hardware reference for executing disconnect later*/
    806                 gpphHal4Nfc_Hwref = psHwReference;
    807                 PHDBG_INFO("Hal4:disconnect deferred");
    808             }
    809             else/*execute disconnect*/
    810             {
    811                 RetStatus = phHal4Nfc_Disconnect_Execute(psHwReference);
    812             }
    813         }
    814     }
    815     return RetStatus;
    816 }
    817 
    818 /**Execute Hal4 Disconnect*/
    819 NFCSTATUS phHal4Nfc_Disconnect_Execute(
    820                             phHal_sHwReference_t  *psHwReference
    821                             )
    822 {
    823     NFCSTATUS RetStatus = NFCSTATUS_PENDING;
    824     phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt =
    825         (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
    826     phHal_eSmartMX_Mode_t SmxMode = eSmartMx_Default;
    827     PHDBG_INFO("Hal4:Inside Hal4 disconnect execute");
    828     switch(Hal4Ctxt->sTgtConnectInfo.ReleaseType)
    829     {
    830         /*Switch mode to Default*/
    831         case NFC_SMARTMX_RELEASE:
    832             SmxMode = eSmartMx_Default;
    833             RetStatus = phHciNfc_Switch_SmxMode (
    834                 Hal4Ctxt->psHciHandle,
    835                 psHwReference,
    836                 SmxMode,
    837                 &(Hal4Ctxt->psADDCtxtInfo->sADDCfg)
    838                 );
    839             break;
    840         /*Disconnect and continue polling wheel*/
    841         case NFC_DISCOVERY_CONTINUE:
    842         {
    843             RetStatus = phHciNfc_Disconnect (
    844                                     Hal4Ctxt->psHciHandle,
    845                                     psHwReference,
    846                                     FALSE
    847                                     );
    848             if(NFCSTATUS_PENDING != RetStatus)
    849             {
    850                 PHDBG_INFO("Hal4:Hci disconnect failed.Restarting discovery");
    851                 RetStatus = phHciNfc_Restart_Discovery (
    852                                     (void *)Hal4Ctxt->psHciHandle,
    853                                     (void *)gpphHal4Nfc_Hwref,
    854                                     FALSE
    855                                     );
    856                 if(NFCSTATUS_PENDING != RetStatus)
    857                 {
    858                     PHDBG_INFO("Hal4:Hci Restart discovery also failed");
    859                 }
    860             }
    861             break;
    862         }
    863         /*Disconnect and restart polling wheel*/
    864         case NFC_DISCOVERY_RESTART:
    865             RetStatus = phHciNfc_Disconnect (
    866                                 Hal4Ctxt->psHciHandle,
    867                                 psHwReference,
    868                                 TRUE
    869                                 );
    870             break;
    871         default:
    872             RetStatus = PHNFCSTVAL(CID_NFC_HAL,
    873                 NFCSTATUS_FEATURE_NOT_SUPPORTED);
    874             break;
    875     }
    876     Hal4Ctxt->sTgtConnectInfo.ReleaseType = NFC_INVALID_RELEASE_TYPE;
    877     /*Update or rollback next state*/
    878     Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == RetStatus?
    879                     eHal4StateOpenAndReady:Hal4Ctxt->Hal4NextState);
    880     return  RetStatus;
    881 }
    882 
    883 /*The function allows to check for presence in vicinity of connected remote
    884   device.*/
    885 NFCSTATUS phHal4Nfc_PresenceCheck(
    886                                 phHal_sHwReference_t     *psHwReference,
    887                                 pphHal4Nfc_GenCallback_t  pPresenceChkCb,
    888                                 void *context
    889                                 )
    890 {
    891     NFCSTATUS RetStatus = NFCSTATUS_FAILED;
    892     phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
    893     /*NULL  checks*/
    894     if((NULL == pPresenceChkCb) || (NULL == psHwReference))
    895     {
    896         RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_INVALID_PARAMETER);
    897     }
    898     /*Check Initialised state*/
    899     else if((NULL == psHwReference->hal_context)
    900                         || (((phHal4Nfc_Hal4Ctxt_t *)
    901                                 psHwReference->hal_context)->Hal4CurrentState
    902                                                < eHal4StateOpenAndReady)
    903                         || (((phHal4Nfc_Hal4Ctxt_t *)
    904                                 psHwReference->hal_context)->Hal4NextState
    905                                                == eHal4StateClosed))
    906     {
    907         PHDBG_INFO("HAL4:Context not Open");
    908         RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_NOT_INITIALISED);
    909     }
    910     /*check connected state and session alive*/
    911     else if((((phHal4Nfc_Hal4Ctxt_t *)
    912              psHwReference->hal_context)->Hal4CurrentState
    913                                 < eHal4StateTargetConnected)||
    914             (NULL == ((phHal4Nfc_Hal4Ctxt_t *)
    915               psHwReference->hal_context)->sTgtConnectInfo.psConnectedDevice)||
    916             (FALSE == ((phHal4Nfc_Hal4Ctxt_t *)
    917                         psHwReference->hal_context)->sTgtConnectInfo.
    918                                     psConnectedDevice->SessionOpened))
    919     {
    920         PHDBG_INFO("HAL4:No target connected");
    921         RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_RELEASED);
    922     }
    923     else
    924     {
    925         Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
    926         /*allow only one Presence chk command at any point in time*/
    927         if (eHal4StatePresenceCheck != Hal4Ctxt->Hal4NextState)
    928         {
    929             Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = context;
    930             Hal4Ctxt->sTgtConnectInfo.pPresenceChkCb = pPresenceChkCb;
    931             RetStatus = phHciNfc_Presence_Check(Hal4Ctxt->psHciHandle,
    932                                                 psHwReference
    933                                                 );
    934             Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == RetStatus?
    935                 eHal4StatePresenceCheck:Hal4Ctxt->Hal4NextState);
    936         }
    937         else/*Ongoing presence chk*/
    938         {
    939             RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_BUSY);
    940         }
    941     }
    942     return RetStatus;
    943 }
    944 
    945 void phHal4Nfc_PresenceChkComplete(
    946                                    phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
    947                                    void *pInfo
    948                                    )
    949 {
    950     NFCSTATUS RetStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status;
    951     Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
    952     /*Notify to upper layer*/
    953     if(NULL != Hal4Ctxt->sTgtConnectInfo.pPresenceChkCb)
    954     {
    955         Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->SessionOpened
    956                      =(uint8_t)(NFCSTATUS_SUCCESS == RetStatus?TRUE:FALSE);
    957         (*Hal4Ctxt->sTgtConnectInfo.pPresenceChkCb)(
    958                         Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
    959                         RetStatus
    960                         );
    961     }
    962     return;
    963 }
    964 
    965 /*Callback for reactivate target and to select appropriate target incase
    966  of multiple targets*/
    967 void phHal4Nfc_ReactivationComplete(
    968                                     phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
    969                                     void *pInfo
    970                                     )
    971 {
    972     NFCSTATUS Status = ((phNfc_sCompletionInfo_t *)pInfo)->status;
    973     /*A NFCSTATUS_SUCCESS status returned here means that the correct device
    974      to connect to has now been selected.So issue connect from here to complete
    975      activation*/
    976     if(NFCSTATUS_SUCCESS == Status)
    977     {
    978         Hal4Ctxt->Hal4NextState = eHal4StateTargetConnected;
    979         Status = phHciNfc_Connect(
    980             Hal4Ctxt->psHciHandle,
    981             gpphHal4Nfc_Hwref,
    982             Hal4Ctxt->sTgtConnectInfo.psConnectedDevice
    983             );
    984         Status = (NFCSTATUS_PENDING == Status)?
    985                     NFCSTATUS_PENDING:NFCSTATUS_FAILED;
    986     }
    987     else/*Device unavailable, return error in connect Callback*/
    988     {
    989         Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
    990         if(NULL != Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb)
    991         {
    992             (*Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb)(
    993                                 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
    994                                 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
    995                                 Status
    996                                 );
    997         }
    998     }
    999     return;
   1000 }
   1001 
   1002 
   1003 void phHal4Nfc_ConnectComplete(
   1004                                phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
   1005                                void *pInfo
   1006                                )
   1007 {
   1008     NFCSTATUS ConnectStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status;
   1009     pphHal4Nfc_ConnectCallback_t pUpperConnectCb
   1010                                 = Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb;
   1011     /*Flag to decide whether or not upper layer callback has to be called*/
   1012     uint8_t CallConnectCb = TRUE;
   1013     /*Remote device Connect successful*/
   1014     if((NFCSTATUS_SUCCESS == ConnectStatus)
   1015 		||(eHal4StateTargetConnected == Hal4Ctxt->Hal4CurrentState))
   1016     {
   1017         PHDBG_INFO("Hal4:Connect status Success");
   1018         Hal4Ctxt->Hal4CurrentState = eHal4StateTargetConnected;
   1019         Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
   1020         /* Open the Session */
   1021         Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->SessionOpened =
   1022             (uint8_t)(NFCSTATUS_SUCCESS == ConnectStatus?TRUE:FALSE);
   1023         Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL;
   1024 
   1025     }
   1026     else/*Remote device Connect failed*/
   1027     {
   1028         Hal4Ctxt->Hal4CurrentState = eHal4StateOpenAndReady;
   1029         Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->SessionOpened = FALSE;
   1030         /*For a NfcIp1 target and case where it is not a internal reconnect
   1031           from Hal4 ,notify callback to upper layer*/
   1032         if((phHal_eNfcIP1_Target
   1033             == Hal4Ctxt->rem_dev_list[0]->RemDevType)
   1034             || (NULL != Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb))
   1035         {
   1036             Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL;
   1037         }
   1038         else/*do not notify callback*/
   1039         {
   1040             CallConnectCb = FALSE;
   1041         }
   1042         /*Free the remote device list*/
   1043         do
   1044         {
   1045             Hal4Ctxt->psADDCtxtInfo->nbr_of_devices--;
   1046             if(NULL != Hal4Ctxt->rem_dev_list[
   1047                         Hal4Ctxt->psADDCtxtInfo->nbr_of_devices])
   1048             {
   1049                 phOsalNfc_FreeMemory((void *)
   1050                         (Hal4Ctxt->rem_dev_list[
   1051                             Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]));
   1052                 Hal4Ctxt->rem_dev_list[
   1053                     Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] = NULL;
   1054             }
   1055         }while(0 < Hal4Ctxt->psADDCtxtInfo->nbr_of_devices);
   1056 
   1057         Hal4Ctxt->sTgtConnectInfo.psConnectedDevice = NULL;
   1058     }
   1059     if(TRUE == CallConnectCb)
   1060     {
   1061         PHDBG_INFO("Hal4:Calling Connect callback");
   1062         /*Notify to the upper layer*/
   1063         (*pUpperConnectCb)(
   1064                     Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
   1065                     Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
   1066                     ConnectStatus
   1067                     );
   1068     }
   1069     else
   1070     {
   1071         PHDBG_INFO("Hal4:Connect failed ,Restarting discovery");
   1072         /*Restart the Discovery wheel*/
   1073         ConnectStatus = phHciNfc_Restart_Discovery (
   1074                                     (void *)Hal4Ctxt->psHciHandle,
   1075                                     (void *)gpphHal4Nfc_Hwref,
   1076                                     FALSE
   1077                                     );
   1078         Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == ConnectStatus?
   1079                                     eHal4StateConfiguring:eHal4StateInvalid);
   1080     }
   1081     return;
   1082 }
   1083 
   1084 
   1085 
   1086 
   1087 void phHal4Nfc_DisconnectComplete(
   1088                                   phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
   1089                                   void *pInfo
   1090                                   )
   1091 {
   1092     NFCSTATUS ConnectStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status;
   1093     phHal_sRemoteDevInformation_t *psConnectedDevice = NULL;
   1094     pphHal4Nfc_DiscntCallback_t pUpperDisconnectCb = NULL;
   1095     pphHal4Nfc_TransceiveCallback_t pUpperTrcvCb = NULL;
   1096     PHDBG_INFO("Hal4:Inside Hal4 disconnect callback");
   1097     if(NULL == Hal4Ctxt)
   1098     {
   1099         phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
   1100     }
   1101     else if(NFCSTATUS_SUCCESS != ConnectStatus)/*Restart the Discovery wheel*/
   1102     {
   1103         ConnectStatus = phHciNfc_Restart_Discovery (
   1104                                     (void *)Hal4Ctxt->psHciHandle,
   1105                                     (void *)gpphHal4Nfc_Hwref,
   1106                                     FALSE
   1107                                     );
   1108         Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == ConnectStatus?
   1109                                     eHal4StateConfiguring:eHal4StateInvalid);
   1110     }
   1111     else/*Remote device Disconnect successful*/
   1112     {
   1113         psConnectedDevice = Hal4Ctxt->sTgtConnectInfo.psConnectedDevice;
   1114         pUpperDisconnectCb = Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb;
   1115         /*Deallocate psTrcvCtxtInfo*/
   1116         if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
   1117         {
   1118             if(NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
   1119             {
   1120                if(NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData)
   1121                 {
   1122                     phOsalNfc_FreeMemory(
   1123                         Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData);
   1124                 }
   1125             }
   1126             else
   1127             {
   1128                 if(phHal_eNfcIP1_Target
   1129                     == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemDevType)
   1130                 {
   1131                     pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb;
   1132                     Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length = 0;
   1133                     pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb;
   1134                     Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL;
   1135                 }
   1136             }
   1137             if(NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer)
   1138             {
   1139                 phOsalNfc_FreeMemory(
   1140                     Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer);
   1141             }
   1142 
   1143             phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo);
   1144             Hal4Ctxt->psTrcvCtxtInfo = NULL;
   1145         }
   1146         /*Free the remote device list*/
   1147         do
   1148         {
   1149             if(NULL != Hal4Ctxt->rem_dev_list[Hal4Ctxt->
   1150                 psADDCtxtInfo->nbr_of_devices-1])
   1151             {
   1152                 phOsalNfc_FreeMemory((void *)
   1153                     (Hal4Ctxt->rem_dev_list[Hal4Ctxt->
   1154                     psADDCtxtInfo->nbr_of_devices-1]));
   1155                 Hal4Ctxt->rem_dev_list[Hal4Ctxt->
   1156                     psADDCtxtInfo->nbr_of_devices-1] = NULL;
   1157             }
   1158         }while(--(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices));
   1159 
   1160         Hal4Ctxt->sTgtConnectInfo.psConnectedDevice = NULL;
   1161         /*Disconnect successful.Go to Ready state*/
   1162         Hal4Ctxt->Hal4CurrentState = Hal4Ctxt->Hal4NextState;
   1163         Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb = NULL;
   1164         Hal4Ctxt->Hal4NextState = (
   1165             eHal4StateOpenAndReady == Hal4Ctxt->Hal4NextState?
   1166             eHal4StateInvalid:Hal4Ctxt->Hal4NextState);
   1167         /*Issue any pending Trcv callback*/
   1168         if(NULL != pUpperTrcvCb)
   1169         {
   1170             (*pUpperTrcvCb)(
   1171                 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
   1172                 psConnectedDevice,
   1173                 NULL,
   1174                 NFCSTATUS_FAILED
   1175                 );
   1176         }
   1177         /*Notify upper layer*/
   1178         if(NULL != pUpperDisconnectCb)
   1179         {
   1180             PHDBG_INFO("Hal4:Calling Upper layer disconnect callback");
   1181             (*pUpperDisconnectCb)(
   1182                         Hal4Ctxt->sUpperLayerInfo.psUpperLayerDisconnectCtxt,
   1183                         psConnectedDevice,
   1184                         ConnectStatus
   1185                         );
   1186         }
   1187     }
   1188     return;
   1189 }
   1190 
   1191 
   1192 /*Transceive complete handler function*/
   1193 void phHal4Nfc_TransceiveComplete(
   1194                                   phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
   1195                                   void *pInfo
   1196                                   )
   1197 {
   1198     /*Copy status code*/
   1199     NFCSTATUS TrcvStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status;
   1200     /*Update next state*/
   1201     Hal4Ctxt->Hal4NextState = (eHal4StateTransaction
   1202              == Hal4Ctxt->Hal4NextState?eHal4StateInvalid:Hal4Ctxt->Hal4NextState);
   1203     /*Reset SelectSectorFlag for Mifare*/
   1204     if (Hal4Ctxt->SelectSectorFlag == 2)
   1205     {
   1206         TrcvStatus = NFCSTATUS_SUCCESS;
   1207         PHDBG_INFO("Inside Hal4TrcvComplete SelectSectorFlag is 2");
   1208         Hal4Ctxt->SelectSectorFlag = 0;
   1209     }
   1210 
   1211     if(NULL == Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData)
   1212     {
   1213         /*if recv buffer is Null*/
   1214         phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
   1215         TrcvStatus = NFCSTATUS_FAILED;
   1216     }
   1217     else if(TrcvStatus == NFCSTATUS_SUCCESS)
   1218     {
   1219         /*Check if recvdata buffer given by upper layer is big enough to
   1220         receive all response bytes.If it is not big enough ,copy number
   1221         of bytes requested by upper layer to the buffer.Remaining
   1222         bytes are retained in Hal4 and upper layer has to issue another
   1223         transceive call to read the same.*/
   1224         if(((phNfc_sTransactionInfo_t *)pInfo)
   1225             ->length  > Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length )
   1226         {
   1227             TrcvStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_MORE_INFORMATION);
   1228             Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length
   1229                 = ((phNfc_sTransactionInfo_t *)pInfo)->length
   1230                 - Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length;
   1231 
   1232             Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer
   1233                 = (uint8_t *)phOsalNfc_GetMemory(
   1234                 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length
   1235                 );
   1236             if(NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer)
   1237             {
   1238                 (void)memcpy(
   1239                     Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer,
   1240                     (((phNfc_sTransactionInfo_t *)pInfo)->buffer
   1241                     + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData
   1242                     ->length)
   1243                     ,Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length
   1244                     );
   1245             }
   1246             else
   1247             {
   1248                 TrcvStatus = PHNFCSTVAL(CID_NFC_HAL,
   1249                     NFCSTATUS_INSUFFICIENT_RESOURCES);
   1250                 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
   1251             }
   1252 
   1253         }
   1254         else/*Buffer provided by upper layer is big enough to hold all read
   1255               bytes*/
   1256         {
   1257             Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length
   1258                 = ((phNfc_sTransactionInfo_t *)pInfo)->length;
   1259             Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length = 0;
   1260         }
   1261         (void)memcpy(Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->buffer,
   1262             ((phNfc_sTransactionInfo_t *)pInfo)->buffer,
   1263             Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length
   1264             );
   1265 
   1266     }
   1267     else/*Error scenario.Set received bytes length to zero*/
   1268     {
   1269         Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length = 0;
   1270     }
   1271     (void)memset((void *)&(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params),
   1272                   0,
   1273                   sizeof(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params)
   1274                 );
   1275     Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset = 0;
   1276     /*Issue transceive callback*/
   1277     (*Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb)(
   1278         Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
   1279         Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
   1280         Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData,
   1281         TrcvStatus
   1282         );
   1283     return;
   1284 }
   1285