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