Home | History | Annotate | Download | only in dnld
      1 /*
      2  * Copyright (C) 2010-2014 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 /*
     18  * Download Component
     19  * Download Interface routines implementation
     20  */
     21 
     22 #include <dlfcn.h>
     23 #include <phDnldNfc_Internal.h>
     24 #include <phNxpConfig.h>
     25 #include <phNxpLog.h>
     26 #include <phTmlNfc.h>
     27 #include <string>
     28 static void* pFwHandle; /* Global firmware handle */
     29 uint16_t wMwVer = 0;    /* Middleware version no */
     30 uint16_t wFwVer = 0;    /* Firmware version no */
     31 uint8_t gRecFWDwnld;    // flag set to true to indicate dummy FW download
     32 phTmlNfc_i2cfragmentation_t fragmentation_enabled = I2C_FRAGMENATATION_DISABLED;
     33 static pphDnldNfc_DlContext_t gpphDnldContext = NULL; /* Download contex */
     34 #undef EEPROM_Read_Mem_IMP
     35 
     36 /*******************************************************************************
     37 **
     38 ** Function         phDnldNfc_Reset
     39 **
     40 ** Description      Performs a soft reset of the download module
     41 **
     42 ** Parameters       pNotify  - notify caller after getting response
     43 **                  pContext - caller context
     44 **
     45 ** Returns          NFC status:
     46 **                  NFCSTATUS_SUCCESS - reset request to NFCC is successful
     47 **                  NFCSTATUS_FAILED - reset request failed due to internal
     48 **                                     error
     49 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
     50 **                  Other command specific errors
     51 **
     52 *******************************************************************************/
     53 NFCSTATUS phDnldNfc_Reset(pphDnldNfc_RspCb_t pNotify, void* pContext) {
     54   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
     55 
     56   if ((NULL == pNotify) || (NULL == pContext)) {
     57     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
     58     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
     59   } else {
     60     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
     61       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
     62       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
     63     } else {
     64       (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
     65       (gpphDnldContext->tCmdId) = PH_DL_CMD_RESET;
     66       (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
     67       (gpphDnldContext->tRspBuffInfo.wLen) = 0;
     68       (gpphDnldContext->tUserData.pBuff) = NULL;
     69       (gpphDnldContext->tUserData.wLen) = 0;
     70       (gpphDnldContext->UserCb) = pNotify;
     71       (gpphDnldContext->UserCtxt) = pContext;
     72 
     73       wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventReset);
     74 
     75       if (NFCSTATUS_PENDING == wStatus) {
     76         NXPLOG_FWDNLD_D("Reset Request submitted successfully");
     77       } else {
     78         NXPLOG_FWDNLD_E("Reset Request Failed!!");
     79       }
     80     }
     81   }
     82 
     83   return wStatus;
     84 }
     85 
     86 /*******************************************************************************
     87 **
     88 ** Function         phDnldNfc_GetVersion
     89 **
     90 ** Description      Retrieves Hardware version, ROM Code version, Protected Data
     91 **                  version, Trim data version, User data version, and Firmware
     92 **                  version information
     93 **
     94 ** Parameters       pVersionInfo - response buffer which gets updated with
     95 **                                 complete version info from NFCC
     96 **                  pNotify - notify caller after getting response
     97 **                  pContext - caller context
     98 **
     99 ** Returns          NFC status:
    100 **                  NFCSTATUS_SUCCESS - GetVersion request to NFCC is successful
    101 **                  NFCSTATUS_FAILED - GetVersion request failed due to internal
    102 **                                     error
    103 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
    104 **                  Other command specific errors
    105 **
    106 *******************************************************************************/
    107 NFCSTATUS phDnldNfc_GetVersion(pphDnldNfc_Buff_t pVersionInfo,
    108                                pphDnldNfc_RspCb_t pNotify, void* pContext) {
    109   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    110 
    111   if ((NULL == pVersionInfo) || (NULL == pNotify) || (NULL == pContext)) {
    112     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
    113     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
    114   } else {
    115     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
    116       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
    117       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
    118     } else {
    119       if ((NULL != pVersionInfo->pBuff) && (0 != pVersionInfo->wLen)) {
    120         (gpphDnldContext->tRspBuffInfo.pBuff) = pVersionInfo->pBuff;
    121         (gpphDnldContext->tRspBuffInfo.wLen) = pVersionInfo->wLen;
    122         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
    123         (gpphDnldContext->tCmdId) = PH_DL_CMD_GETVERSION;
    124         (gpphDnldContext->tUserData.pBuff) = NULL;
    125         (gpphDnldContext->tUserData.wLen) = 0;
    126         (gpphDnldContext->UserCb) = pNotify;
    127         (gpphDnldContext->UserCtxt) = pContext;
    128 
    129         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventGetVer);
    130 
    131         if (NFCSTATUS_PENDING == wStatus) {
    132           NXPLOG_FWDNLD_D("GetVersion Request submitted successfully");
    133         } else {
    134           NXPLOG_FWDNLD_E("GetVersion Request Failed!!");
    135         }
    136       } else {
    137         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
    138         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
    139       }
    140     }
    141   }
    142 
    143   return wStatus;
    144 }
    145 
    146 /*******************************************************************************
    147 **
    148 ** Function         phDnldNfc_GetSessionState
    149 **
    150 ** Description      Retrieves the current session state of NFCC
    151 **
    152 ** Parameters       pSession - response buffer which gets updated with complete
    153 **                             version info from NFCC
    154 **                  pNotify - notify caller after getting response
    155 **                  pContext - caller context
    156 **
    157 ** Returns          NFC status:
    158 **                  NFCSTATUS_SUCCESS - GetSessionState request to NFCC is
    159 **                                      successful
    160 **                  NFCSTATUS_FAILED - GetSessionState request failed due to
    161 **                                     internal error
    162 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
    163 **                  Other command specific errors
    164 **
    165 *******************************************************************************/
    166 NFCSTATUS phDnldNfc_GetSessionState(pphDnldNfc_Buff_t pSession,
    167                                     pphDnldNfc_RspCb_t pNotify,
    168                                     void* pContext) {
    169   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    170 
    171   if ((NULL == pSession) || (NULL == pNotify) || (NULL == pContext)) {
    172     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
    173     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
    174   } else {
    175     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
    176       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
    177       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
    178     } else {
    179       if ((NULL != pSession->pBuff) && (0 != pSession->wLen)) {
    180         (gpphDnldContext->tRspBuffInfo.pBuff) = pSession->pBuff;
    181         (gpphDnldContext->tRspBuffInfo.wLen) = pSession->wLen;
    182         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
    183         (gpphDnldContext->tCmdId) = PH_DL_CMD_GETSESSIONSTATE;
    184         (gpphDnldContext->tUserData.pBuff) = NULL;
    185         (gpphDnldContext->tUserData.wLen) = 0;
    186         (gpphDnldContext->UserCb) = pNotify;
    187         (gpphDnldContext->UserCtxt) = pContext;
    188 
    189         wStatus =
    190             phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventGetSesnSt);
    191 
    192         if (NFCSTATUS_PENDING == wStatus) {
    193           NXPLOG_FWDNLD_D("GetSessionState Request submitted successfully");
    194         } else {
    195           NXPLOG_FWDNLD_E("GetSessionState Request Failed!!");
    196         }
    197       } else {
    198         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
    199         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
    200       }
    201     }
    202   }
    203 
    204   return wStatus;
    205 }
    206 
    207 /*******************************************************************************
    208 **
    209 ** Function         phDnldNfc_CheckIntegrity
    210 **
    211 ** Description      Inspects the integrity of EEPROM and FLASH contents of the
    212 **                  NFCC, provides CRC for each section
    213 **                  NOTE: The user data section CRC is valid only after fresh
    214 **                        download
    215 **
    216 ** Parameters       bChipVer - current ChipVersion for including additional
    217 **                             parameters in request payload
    218 **                  pCRCData - response buffer which gets updated with
    219 **                             respective section CRC status and CRC bytes from
    220 **                             NFCC
    221 **                  pNotify - notify caller after getting response
    222 **                  pContext - caller context
    223 **
    224 ** Returns          NFC status:
    225 **                  NFCSTATUS_SUCCESS - CheckIntegrity request is successful
    226 **                  NFCSTATUS_FAILED - CheckIntegrity request failed due to
    227 **                                     internal error
    228 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
    229 **                  Other command specific errors
    230 **
    231 *******************************************************************************/
    232 NFCSTATUS phDnldNfc_CheckIntegrity(uint8_t bChipVer, pphDnldNfc_Buff_t pCRCData,
    233                                    pphDnldNfc_RspCb_t pNotify, void* pContext) {
    234   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    235 
    236   if ((NULL == pNotify) || (NULL == pContext)) {
    237     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
    238     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
    239   } else {
    240     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
    241       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
    242       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
    243     } else {
    244       if ((PHDNLDNFC_HWVER_MRA2_1 == bChipVer) ||
    245           (PHDNLDNFC_HWVER_MRA2_2 == bChipVer) ||
    246           ((nfcFL.chipType == pn551) &&
    247            (PHDNLDNFC_HWVER_PN551_MRA1_0 == bChipVer)) ||
    248           (((nfcFL.chipType == pn553) || (nfcFL.chipType == pn557)) &&
    249            ((PHDNLDNFC_HWVER_PN553_MRA1_0 == bChipVer) ||
    250             (PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & bChipVer) ||
    251             (PHDNLDNFC_HWVER_PN557_MRA1_0 == bChipVer)))) {
    252         (gpphDnldContext->FrameInp.Type) = phDnldNfc_ChkIntg;
    253       } else {
    254         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
    255       }
    256 
    257       if ((NULL != pCRCData->pBuff) && (0 != pCRCData->wLen)) {
    258         (gpphDnldContext->tRspBuffInfo.pBuff) = pCRCData->pBuff;
    259         (gpphDnldContext->tRspBuffInfo.wLen) = pCRCData->wLen;
    260         (gpphDnldContext->tCmdId) = PH_DL_CMD_CHECKINTEGRITY;
    261         (gpphDnldContext->tUserData.pBuff) = NULL;
    262         (gpphDnldContext->tUserData.wLen) = 0;
    263         (gpphDnldContext->UserCb) = pNotify;
    264         (gpphDnldContext->UserCtxt) = pContext;
    265 
    266         wStatus =
    267             phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventIntegChk);
    268 
    269         if (NFCSTATUS_PENDING == wStatus) {
    270           NXPLOG_FWDNLD_D("CheckIntegrity Request submitted successfully");
    271         } else {
    272           NXPLOG_FWDNLD_E("CheckIntegrity Request Failed!!");
    273         }
    274       } else {
    275         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
    276         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
    277       }
    278     }
    279   }
    280 
    281   return wStatus;
    282 }
    283 /*******************************************************************************
    284 **
    285 ** Function         phDnldNfc_ReadLog
    286 **
    287 ** Description      Retrieves log data from EEPROM
    288 **
    289 ** Parameters       pData - response buffer which gets updated with data from
    290 **                          EEPROM
    291 **                  pNotify - notify caller after getting response
    292 **                  pContext - caller context
    293 **
    294 ** Returns          NFC status:
    295 **                  NFCSTATUS_SUCCESS - Read request to NFCC is successful
    296 **                  NFCSTATUS_FAILED - Read request failed due to internal error
    297 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
    298 **                  Other command specific errors
    299 **
    300 *******************************************************************************/
    301 NFCSTATUS phDnldNfc_ReadLog(pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify,
    302                             void* pContext) {
    303   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    304 
    305   if ((NULL == pNotify) || (NULL == pData) || (NULL == pContext)) {
    306     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
    307     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
    308   } else {
    309     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
    310       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
    311       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
    312     } else {
    313       if ((NULL != pData->pBuff) && (0 != pData->wLen)) {
    314         (gpphDnldContext->tCmdId) = PH_DL_CMD_READ;
    315         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRead;
    316         (gpphDnldContext->FrameInp.dwAddr) = PHDNLDNFC_EEPROM_LOG_START_ADDR;
    317         (gpphDnldContext->tRspBuffInfo.pBuff) = pData->pBuff;
    318         (gpphDnldContext->tRspBuffInfo.wLen) = pData->wLen;
    319         (gpphDnldContext->tUserData.pBuff) = NULL;
    320         (gpphDnldContext->tUserData.wLen) = 0;
    321         (gpphDnldContext->UserCb) = pNotify;
    322         (gpphDnldContext->UserCtxt) = pContext;
    323 
    324         memset(&(gpphDnldContext->tRWInfo), 0,
    325                sizeof(gpphDnldContext->tRWInfo));
    326 
    327         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventRead);
    328 
    329         if (NFCSTATUS_PENDING == wStatus) {
    330           NXPLOG_FWDNLD_D("Read Request submitted successfully");
    331         } else {
    332           NXPLOG_FWDNLD_E("Read Request Failed!!");
    333         }
    334       } else {
    335         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
    336         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
    337       }
    338     }
    339   }
    340 
    341   return wStatus;
    342 }
    343 
    344 /*******************************************************************************
    345 **
    346 ** Function         phDnldNfc_Write
    347 **
    348 ** Description      Writes requested  data of length len to desired EEPROM/FLASH
    349 **                  address
    350 **
    351 ** Parameters       bRecoverSeq - flag to indicate whether recover sequence data
    352 **                                needs to be written or not
    353 **                  pData - data buffer to write into EEPROM/FLASH by user
    354 **                  pNotify - notify caller after getting response
    355 **                  pContext - caller context
    356 **
    357 ** Returns          NFC status:
    358 **                  NFCSTATUS_SUCCESS - Write request to NFCC is successful
    359 **                  NFCSTATUS_FAILED - Write request failed due to internal
    360 **                                     error
    361 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
    362 **                  Other command specific errors
    363 **
    364 *******************************************************************************/
    365 NFCSTATUS phDnldNfc_Write(bool_t bRecoverSeq, pphDnldNfc_Buff_t pData,
    366                           pphDnldNfc_RspCb_t pNotify, void* pContext) {
    367   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    368   uint8_t* pImgPtr = NULL;
    369   uint16_t wLen = 0;
    370   phDnldNfc_Buff_t tImgBuff;
    371 
    372   if ((NULL == pNotify) || (NULL == pContext)) {
    373     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
    374     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
    375   } else {
    376     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
    377       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
    378       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
    379     } else {
    380       if (NULL != pData) {
    381         pImgPtr = pData->pBuff;
    382         wLen = pData->wLen;
    383       } else {
    384         if (bRecoverSeq == false) {
    385           pImgPtr = (uint8_t*)gpphDnldContext->nxp_nfc_fw;
    386           wLen = gpphDnldContext->nxp_nfc_fw_len;
    387 
    388         } else {
    389           if (PH_DL_STATUS_PLL_ERROR == (gpphDnldContext->tLastStatus)) {
    390             wStatus = phDnldNfc_LoadRecInfo();
    391           } else if (PH_DL_STATUS_SIGNATURE_ERROR ==
    392                      (gpphDnldContext->tLastStatus)) {
    393             wStatus = phDnldNfc_LoadPKInfo();
    394           } else {
    395           }
    396 
    397           if (NFCSTATUS_SUCCESS == wStatus) {
    398             pImgPtr = (uint8_t*)gpphDnldContext->nxp_nfc_fwp;
    399             wLen = gpphDnldContext->nxp_nfc_fwp_len;
    400           } else {
    401             NXPLOG_FWDNLD_E("Platform Recovery Image extraction Failed!!");
    402             pImgPtr = NULL;
    403             wLen = 0;
    404           }
    405         }
    406       }
    407 
    408       if ((NULL != pImgPtr) && (0 != wLen)) {
    409         tImgBuff.pBuff = pImgPtr;
    410         tImgBuff.wLen = wLen;
    411 
    412         (gpphDnldContext->tCmdId) = PH_DL_CMD_WRITE;
    413         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTWrite;
    414         (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
    415         (gpphDnldContext->tRspBuffInfo.wLen) = 0;
    416         (gpphDnldContext->tUserData.pBuff) = pImgPtr;
    417         (gpphDnldContext->tUserData.wLen) = wLen;
    418         (gpphDnldContext->bResendLastFrame) = false;
    419 
    420         memset(&(gpphDnldContext->tRWInfo), 0,
    421                sizeof(gpphDnldContext->tRWInfo));
    422         (gpphDnldContext->tRWInfo.bFirstWrReq) = true;
    423         (gpphDnldContext->UserCb) = pNotify;
    424         (gpphDnldContext->UserCtxt) = pContext;
    425 
    426         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventWrite);
    427 
    428         if (NFCSTATUS_PENDING == wStatus) {
    429           NXPLOG_FWDNLD_D("Write Request submitted successfully");
    430         } else {
    431           NXPLOG_FWDNLD_E("Write Request Failed!!");
    432         }
    433       } else {
    434         NXPLOG_FWDNLD_E("Download Image Primitives extraction failed!!");
    435         wStatus = NFCSTATUS_FAILED;
    436       }
    437     }
    438   }
    439 
    440   return wStatus;
    441 }
    442 
    443 /*******************************************************************************
    444 **
    445 ** Function         phDnldNfc_Log
    446 **
    447 ** Description      Provides a full page free write to EEPROM
    448 **
    449 ** Parameters       pData - data buffer to write into EEPROM/FLASH by user
    450 **                  pNotify - notify caller after getting response
    451 **                  pContext - caller context
    452 **
    453 ** Returns          NFC status:
    454 **                  NFCSTATUS_SUCCESS - Write request to NFCC is successful
    455 **                  NFCSTATUS_FAILED - Write request failed due to internal
    456 **                                     error
    457 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
    458 **                  Other command specific error
    459 **
    460 *******************************************************************************/
    461 NFCSTATUS phDnldNfc_Log(pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify,
    462                         void* pContext) {
    463   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    464 
    465   if ((NULL == pNotify) || (NULL == pData) || (NULL == pContext)) {
    466     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
    467     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
    468   } else {
    469     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
    470       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
    471       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
    472     } else {
    473       if ((NULL != (pData->pBuff)) &&
    474           ((0 != (pData->wLen) && (PHDNLDNFC_MAX_LOG_SIZE >= (pData->wLen))))) {
    475         (gpphDnldContext->tCmdId) = PH_DL_CMD_LOG;
    476         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTLog;
    477         (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
    478         (gpphDnldContext->tRspBuffInfo.wLen) = 0;
    479         (gpphDnldContext->tUserData.pBuff) = (pData->pBuff);
    480         (gpphDnldContext->tUserData.wLen) = (pData->wLen);
    481 
    482         memset(&(gpphDnldContext->tRWInfo), 0,
    483                sizeof(gpphDnldContext->tRWInfo));
    484         (gpphDnldContext->UserCb) = pNotify;
    485         (gpphDnldContext->UserCtxt) = pContext;
    486 
    487         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventLog);
    488 
    489         if (NFCSTATUS_PENDING == wStatus) {
    490           NXPLOG_FWDNLD_D("Log Request submitted successfully");
    491         } else {
    492           NXPLOG_FWDNLD_E("Log Request Failed!!");
    493         }
    494       } else {
    495         NXPLOG_FWDNLD_E("Invalid Input Parameters for Log!!");
    496         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
    497       }
    498     }
    499   }
    500 
    501   return wStatus;
    502 }
    503 
    504 /*******************************************************************************
    505 **
    506 ** Function         phDnldNfc_Force
    507 **
    508 ** Description      Used as an emergency recovery procedure for NFCC due to
    509 **                  corrupt settings of system platform specific parameters by
    510 **                  the host
    511 **
    512 ** Parameters       pInputs - input buffer which contains  clk src & clk freq
    513 **                            settings for desired platform
    514 **                  pNotify - notify caller after getting response
    515 **                  pContext - caller context
    516 **
    517 ** Returns          NFC status:
    518 **                  NFCSTATUS_SUCCESS - Emergency Recovery request is successful
    519 **                  NFCSTATUS_FAILED - Emergency Recovery failed due to internal
    520 **                                     error
    521 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
    522 **                  Other command specific errors
    523 **
    524 *******************************************************************************/
    525 NFCSTATUS phDnldNfc_Force(pphDnldNfc_Buff_t pInputs, pphDnldNfc_RspCb_t pNotify,
    526                           void* pContext) {
    527   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    528   uint8_t bClkSrc = 0x00, bClkFreq = 0x00;
    529   uint8_t bPldVal[3] = {
    530       0x11, 0x00, 0x00}; /* default values to be used if input not provided */
    531 
    532   if ((NULL == pNotify) || (NULL == pContext)) {
    533     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
    534     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
    535   } else {
    536     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
    537       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
    538       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
    539     } else {
    540       (gpphDnldContext->tCmdId) = PH_DL_CMD_FORCE;
    541       (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTForce;
    542       (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
    543       (gpphDnldContext->tRspBuffInfo.wLen) = 0;
    544 
    545       if ((0 != (pInputs->wLen)) || (NULL != (pInputs->pBuff))) {
    546         if (CLK_SRC_XTAL == (pInputs->pBuff[0])) {
    547           bClkSrc = phDnldNfc_ClkSrcXtal;
    548         } else if (CLK_SRC_PLL == (pInputs->pBuff[0])) {
    549           bClkSrc = phDnldNfc_ClkSrcPLL;
    550           if (CLK_FREQ_13MHZ == (pInputs->pBuff[1])) {
    551             bClkFreq = phDnldNfc_ClkFreq_13Mhz;
    552           } else if (CLK_FREQ_19_2MHZ == (pInputs->pBuff[1])) {
    553             bClkFreq = phDnldNfc_ClkFreq_19_2Mhz;
    554           } else if (CLK_FREQ_24MHZ == (pInputs->pBuff[1])) {
    555             bClkFreq = phDnldNfc_ClkFreq_24Mhz;
    556           } else if (CLK_FREQ_26MHZ == (pInputs->pBuff[1])) {
    557             bClkFreq = phDnldNfc_ClkFreq_26Mhz;
    558           } else if (CLK_FREQ_38_4MHZ == (pInputs->pBuff[1])) {
    559             bClkFreq = phDnldNfc_ClkFreq_38_4Mhz;
    560           } else if (CLK_FREQ_52MHZ == (pInputs->pBuff[1])) {
    561             bClkFreq = phDnldNfc_ClkFreq_52Mhz;
    562           } else {
    563             NXPLOG_FWDNLD_E(
    564                 "Invalid Clk Frequency !! Using default value of 19.2Mhz..");
    565             bClkFreq = phDnldNfc_ClkFreq_19_2Mhz;
    566           }
    567 
    568         } else if (CLK_SRC_PADDIRECT == (pInputs->pBuff[0])) {
    569           bClkSrc = phDnldNfc_ClkSrcPad;
    570         } else {
    571           NXPLOG_FWDNLD_E("Invalid Clk src !! Using default value of PLL..");
    572           bClkSrc = phDnldNfc_ClkSrcPLL;
    573         }
    574 
    575         bPldVal[0] = 0U;
    576         bPldVal[0] = ((bClkSrc << 3U) | bClkFreq);
    577       } else {
    578         NXPLOG_FWDNLD_E("Clk src inputs not provided!! Using default values..");
    579       }
    580 
    581       (gpphDnldContext->tUserData.pBuff) = bPldVal;
    582       (gpphDnldContext->tUserData.wLen) = sizeof(bPldVal);
    583 
    584       memset(&(gpphDnldContext->tRWInfo), 0, sizeof(gpphDnldContext->tRWInfo));
    585       (gpphDnldContext->UserCb) = pNotify;
    586       (gpphDnldContext->UserCtxt) = pContext;
    587 
    588       wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventForce);
    589 
    590       if (NFCSTATUS_PENDING == wStatus) {
    591         NXPLOG_FWDNLD_D("Force Command Request submitted successfully");
    592       } else {
    593         NXPLOG_FWDNLD_E("Force Command Request Failed!!");
    594       }
    595     }
    596   }
    597 
    598   return wStatus;
    599 }
    600 
    601 /*******************************************************************************
    602 **
    603 ** Function         phDnldNfc_SetHwDevHandle
    604 **
    605 ** Description      Stores the HwDev handle to download context. The handle is
    606 **                  required for subsequent operations
    607 **
    608 ** Parameters       None
    609 **
    610 ** Returns          None                -
    611 **
    612 *******************************************************************************/
    613 void phDnldNfc_SetHwDevHandle(void) {
    614   pphDnldNfc_DlContext_t psDnldContext = NULL;
    615 
    616   if (NULL == gpphDnldContext) {
    617     NXPLOG_FWDNLD_D("Allocating Mem for Dnld Context..");
    618     /* Create the memory for Download Mgmt Context */
    619     psDnldContext =
    620         (pphDnldNfc_DlContext_t)malloc(sizeof(phDnldNfc_DlContext_t));
    621 
    622     if (psDnldContext != NULL) {
    623       (void)memset((void*)psDnldContext, 0, sizeof(phDnldNfc_DlContext_t));
    624       gpphDnldContext = psDnldContext;
    625     } else {
    626       NXPLOG_FWDNLD_E("Error Allocating Mem for Dnld Context..")
    627     }
    628   } else {
    629     (void)memset((void*)gpphDnldContext, 0, sizeof(phDnldNfc_DlContext_t));
    630   }
    631   return;
    632 }
    633 
    634 /*******************************************************************************
    635 **
    636 ** Function         phDnldNfc_ReSetHwDevHandle
    637 **
    638 ** Description      Frees the HwDev handle to download context.
    639 **
    640 ** Parameters       None
    641 **
    642 ** Returns          None                -
    643 **
    644 *******************************************************************************/
    645 void phDnldNfc_ReSetHwDevHandle(void) {
    646   if (gpphDnldContext != NULL) {
    647     NXPLOG_FWDNLD_E("Freeing Mem for Dnld Context..")
    648     free(gpphDnldContext);
    649     gpphDnldContext = NULL;
    650   }
    651 }
    652 
    653 /*******************************************************************************
    654 **
    655 ** Function         phDnldNfc_RawReq
    656 **
    657 ** Description      Sends raw frame request to NFCC.
    658 **                  It is currently used for sending an NCI RESET cmd after
    659 **                  doing a production key update
    660 **
    661 ** Parameters       pFrameData - input buffer, contains raw frame packet to be
    662 **                               sent to NFCC
    663 **                  pRspData - response buffer received from NFCC
    664 **                  pNotify - notify caller after getting response
    665 **                  pContext - caller context
    666 **
    667 ** Returns          NFC status:
    668 **                  NFCSTATUS_SUCCESS - GetSessionState request to NFCC is
    669 **                                      successful
    670 **                  NFCSTATUS_FAILED - GetSessionState request failed due to
    671 **                                     internal error
    672 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
    673 **                  Other command specific errors
    674 **
    675 *******************************************************************************/
    676 NFCSTATUS phDnldNfc_RawReq(pphDnldNfc_Buff_t pFrameData,
    677                            pphDnldNfc_Buff_t pRspData,
    678                            pphDnldNfc_RspCb_t pNotify, void* pContext) {
    679   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    680 
    681   if ((NULL == pFrameData) || (NULL == pNotify) || (NULL == pRspData) ||
    682       (NULL == pContext)) {
    683     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
    684     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
    685   } else {
    686     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
    687       NXPLOG_FWDNLD_E("Raw Cmd Request in Progress..Cannot Continue!!");
    688       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
    689     } else {
    690       if (((NULL != pFrameData->pBuff) && (0 != pFrameData->wLen)) &&
    691           ((NULL != pRspData->pBuff) && (0 != pRspData->wLen))) {
    692         (gpphDnldContext->tRspBuffInfo.pBuff) = pRspData->pBuff;
    693         (gpphDnldContext->tRspBuffInfo.wLen) = pRspData->wLen;
    694         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRaw;
    695         (gpphDnldContext->tCmdId) = PH_DL_CMD_NONE;
    696         (gpphDnldContext->tUserData.pBuff) = pFrameData->pBuff;
    697         (gpphDnldContext->tUserData.wLen) = pFrameData->wLen;
    698         (gpphDnldContext->UserCb) = pNotify;
    699         (gpphDnldContext->UserCtxt) = pContext;
    700 
    701         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventRaw);
    702 
    703         if (NFCSTATUS_PENDING == wStatus) {
    704           NXPLOG_FWDNLD_D("RawFrame Request submitted successfully");
    705         } else {
    706           NXPLOG_FWDNLD_E("RawFrame Request Failed!!");
    707         }
    708       } else {
    709         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
    710         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
    711       }
    712     }
    713   }
    714 
    715   return wStatus;
    716 }
    717 
    718 /*******************************************************************************
    719 **
    720 ** Function         phDnldNfc_InitImgInfo
    721 **
    722 ** Description      Extracts image information and stores it in respective
    723 **                  variables, to be used internally for write operation
    724 **
    725 ** Parameters       None
    726 **
    727 ** Returns          NFC status
    728 **
    729 *******************************************************************************/
    730 NFCSTATUS phDnldNfc_InitImgInfo(void) {
    731   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    732   uint8_t* pImageInfo = NULL;
    733   uint16_t ImageInfoLen = 0;
    734   unsigned long fwType = FW_FORMAT_SO;
    735 
    736   /* if memory is not allocated then allocate memory for download context
    737    * structure */
    738   phDnldNfc_SetHwDevHandle();
    739 
    740   gpphDnldContext->FwFormat = FW_FORMAT_UNKNOWN;
    741 
    742   /*Read Firmware file name from config file*/
    743   if (GetNxpNumValue(NAME_NXP_FW_TYPE, &fwType, sizeof(fwType)) == true) {
    744     NXPLOG_FWDNLD_D("firmware type from conf file: %lu",fwType);
    745   } else {
    746     NXPLOG_FWDNLD_W("firmware type not found. Taking default value: %lu",fwType);
    747   }
    748 
    749   if(fwType == FW_FORMAT_BIN) {
    750     gpphDnldContext->FwFormat = FW_FORMAT_BIN;
    751     wStatus = phDnldNfc_LoadBinFW(&pImageInfo, &ImageInfoLen);
    752   } else if(fwType == FW_FORMAT_SO) {
    753     gpphDnldContext->FwFormat = FW_FORMAT_SO;
    754     if (gRecFWDwnld == true) {
    755       wStatus = phDnldNfc_LoadRecoveryFW(&pImageInfo, &ImageInfoLen);
    756     } else {
    757       wStatus = phDnldNfc_LoadFW(&pImageInfo, &ImageInfoLen);
    758     }
    759   } else {
    760     NXPLOG_FWDNLD_E("firmware file format mismatch!!!\n");
    761     return NFCSTATUS_FAILED;
    762   }
    763 
    764   NXPLOG_FWDNLD_E("FW Image Length - ImageInfoLen %d", ImageInfoLen);
    765   NXPLOG_FWDNLD_E("FW Image Info Pointer - pImageInfo %p", pImageInfo);
    766 
    767   if ((pImageInfo == NULL) || (ImageInfoLen == 0)) {
    768     NXPLOG_FWDNLD_E(
    769         "Image extraction Failed - invalid imginfo or imginfolen!!");
    770     wStatus = NFCSTATUS_FAILED;
    771   }
    772 
    773   if (wStatus != NFCSTATUS_SUCCESS) {
    774     NXPLOG_FWDNLD_E("Error loading libpn54x_fw !!\n");
    775   }
    776 
    777   /* get the MW version */
    778   if (NFCSTATUS_SUCCESS == wStatus) {
    779     // NXPLOG_FWDNLD_D("MW Major Version Num - %x",NXP_MW_VERSION_MAJ);
    780     // NXPLOG_FWDNLD_D("MW Minor Version Num - %x",NXP_MW_VERSION_MIN);
    781     wMwVer = (((uint16_t)(NXP_MW_VERSION_MAJ) << 8U) | (NXP_MW_VERSION_MIN));
    782   }
    783 
    784   if (NFCSTATUS_SUCCESS == wStatus) {
    785     gpphDnldContext->nxp_nfc_fw = (uint8_t*)pImageInfo;
    786     gpphDnldContext->nxp_nfc_fw_len = ImageInfoLen;
    787     if ((NULL != gpphDnldContext->nxp_nfc_fw) &&
    788         (0 != gpphDnldContext->nxp_nfc_fw_len)) {
    789       NXPLOG_FWDNLD_E("FW Major Version Num - %x",
    790                       gpphDnldContext->nxp_nfc_fw[5]);
    791       NXPLOG_FWDNLD_E("FW Minor Version Num - %x",
    792                       gpphDnldContext->nxp_nfc_fw[4]);
    793       NXPLOG_FWDNLD_E("FW Image Length - %d", ImageInfoLen);
    794       NXPLOG_FWDNLD_E("FW Image Info Pointer - %p", pImageInfo);
    795 
    796       /* get the FW version */
    797       wFwVer = (((uint16_t)(gpphDnldContext->nxp_nfc_fw[5]) << 8U) |
    798                 (gpphDnldContext->nxp_nfc_fw[4]));
    799       wStatus = NFCSTATUS_SUCCESS;
    800     } else {
    801       NXPLOG_FWDNLD_E("Image details extraction Failed!!");
    802       wStatus = NFCSTATUS_FAILED;
    803     }
    804   }
    805 
    806   return wStatus;
    807 }
    808 
    809 /*******************************************************************************
    810 **
    811 ** Function         phDnldNfc_LoadRecInfo
    812 **
    813 ** Description      Extracts recovery sequence image information and stores it
    814 **                  in respective variables, to be used internally for write
    815 **                  operation
    816 **
    817 ** Parameters       None
    818 **
    819 ** Returns          NFC status
    820 **
    821 *******************************************************************************/
    822 NFCSTATUS phDnldNfc_LoadRecInfo(void) {
    823   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    824   uint8_t* pImageInfo = NULL;
    825   uint16_t ImageInfoLen = 0;
    826 
    827   /* if memory is not allocated then allocate memory for donwload context
    828    * structure */
    829   phDnldNfc_SetHwDevHandle();
    830   if (gRecFWDwnld == true)
    831     wStatus = phDnldNfc_LoadRecoveryFW(&pImageInfo, &ImageInfoLen);
    832   else
    833     wStatus = phDnldNfc_LoadFW(&pImageInfo, &ImageInfoLen);
    834 
    835   if ((pImageInfo == NULL) || (ImageInfoLen == 0)) {
    836     NXPLOG_FWDNLD_E(
    837         "Image extraction Failed - invalid imginfo or imginfolen!!");
    838     wStatus = NFCSTATUS_FAILED;
    839   }
    840 
    841   /* load the PLL recovery image library */
    842   if (wStatus != NFCSTATUS_SUCCESS) {
    843     NXPLOG_FWDNLD_E("Error loading libpn54x_fw_platform !!\n");
    844   }
    845 
    846   if (NFCSTATUS_SUCCESS == wStatus) {
    847     /* fetch the PLL recovery image pointer and the image length */
    848     gpphDnldContext->nxp_nfc_fwp = (uint8_t*)pImageInfo;
    849     gpphDnldContext->nxp_nfc_fwp_len = ImageInfoLen;
    850     if ((NULL != gpphDnldContext->nxp_nfc_fwp) &&
    851         (0 != gpphDnldContext->nxp_nfc_fwp_len)) {
    852       NXPLOG_FWDNLD_D("Recovery Image Length - %d", ImageInfoLen);
    853       NXPLOG_FWDNLD_D("Recovery Image Info Pointer - %p", pImageInfo);
    854       wStatus = NFCSTATUS_SUCCESS;
    855     } else {
    856       NXPLOG_FWDNLD_E("Recovery Image details extraction Failed!!");
    857       wStatus = NFCSTATUS_FAILED;
    858     }
    859   }
    860 
    861   return wStatus;
    862 }
    863 
    864 /*******************************************************************************
    865 **
    866 ** Function         phDnldNfc_LoadPKInfo
    867 **
    868 ** Description      Extracts production sequence image information and stores it
    869 **                  in respective variables, to be used internally for write
    870 **                  operation
    871 **
    872 ** Parameters       None
    873 **
    874 ** Returns          NFC status
    875 **
    876 *******************************************************************************/
    877 NFCSTATUS phDnldNfc_LoadPKInfo(void) {
    878   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    879   uint8_t* pImageInfo = NULL;
    880   uint16_t ImageInfoLen = 0;
    881 
    882   /* if memory is not allocated then allocate memory for donwload context
    883    * structure */
    884   phDnldNfc_SetHwDevHandle();
    885   /* load the PKU image library */
    886   if (gRecFWDwnld == true)
    887     wStatus = phDnldNfc_LoadRecoveryFW(&pImageInfo, &ImageInfoLen);
    888   else
    889     wStatus = phDnldNfc_LoadFW(&pImageInfo, &ImageInfoLen);
    890   if ((pImageInfo == NULL) || (ImageInfoLen == 0)) {
    891     NXPLOG_FWDNLD_E(
    892         "Image extraction Failed - invalid imginfo or imginfolen!!");
    893     wStatus = NFCSTATUS_FAILED;
    894   }
    895 
    896   if (wStatus != NFCSTATUS_SUCCESS) {
    897     NXPLOG_FWDNLD_E("Error loading libpn54x_fw_pku !!\n");
    898   }
    899 
    900   if (NFCSTATUS_SUCCESS == wStatus) {
    901     /* fetch the PKU image pointer and the image length */
    902     gpphDnldContext->nxp_nfc_fwp = (uint8_t*)pImageInfo;
    903     gpphDnldContext->nxp_nfc_fwp_len = ImageInfoLen;
    904 
    905     if ((NULL != gpphDnldContext->nxp_nfc_fwp) &&
    906         (0 != gpphDnldContext->nxp_nfc_fwp_len)) {
    907       NXPLOG_FWDNLD_D("PKU Image Length - %d", ImageInfoLen);
    908       NXPLOG_FWDNLD_D("PKU Image Info Pointer - %p", pImageInfo);
    909       wStatus = NFCSTATUS_SUCCESS;
    910     } else {
    911       NXPLOG_FWDNLD_E("PKU Image details extraction Failed!!");
    912       wStatus = NFCSTATUS_FAILED;
    913     }
    914   }
    915 
    916   return wStatus;
    917 }
    918 
    919 /*******************************************************************************
    920 **
    921 ** Function         phDnldNfc_CloseFwLibHandle
    922 **
    923 ** Description      Closes previously opened fw library handle as part of
    924 **                  dynamic loader processing
    925 **
    926 ** Parameters       None
    927 **
    928 ** Returns          None
    929 **
    930 *******************************************************************************/
    931 void phDnldNfc_CloseFwLibHandle(void) {
    932   NFCSTATUS wStatus = NFCSTATUS_FAILED;
    933   if (gpphDnldContext->FwFormat == FW_FORMAT_SO) {
    934     wStatus = phDnldNfc_UnloadFW();
    935     if (wStatus != NFCSTATUS_SUCCESS) {
    936       NXPLOG_FWDNLD_E("free library FAILED !!\n");
    937     } else {
    938       NXPLOG_FWDNLD_E("free library SUCCESS !!\n");
    939     }
    940   } else if (gpphDnldContext->FwFormat == FW_FORMAT_BIN) {
    941     if (pFwHandle != NULL) {
    942       free(pFwHandle);
    943       pFwHandle = NULL;
    944     }
    945   }
    946   return;
    947 }
    948 
    949 /*******************************************************************************
    950 **
    951 ** Function         phDnldNfc_LoadFW
    952 **
    953 ** Description      Load the firmware version form firmware lib
    954 **
    955 ** Parameters       pImgInfo    - Firmware image handle
    956 **                  pImgInfoLen - Firmware image length
    957 **
    958 ** Returns          NFC status
    959 **
    960 *******************************************************************************/
    961 NFCSTATUS phDnldNfc_LoadFW(uint8_t** pImgInfo, uint16_t* pImgInfoLen) {
    962   void* pImageInfo = NULL;
    963   void* pImageInfoLen = NULL;
    964 
    965   /* check if the handle is not NULL then free the library */
    966   if (pFwHandle != NULL) {
    967     phDnldNfc_CloseFwLibHandle();
    968     pFwHandle = NULL;
    969   }
    970 
    971   /* load the DLL file */
    972   pFwHandle = dlopen(nfcFL._FW_LIB_PATH.c_str(), RTLD_LAZY);
    973   NXPLOG_FWDNLD_D("@@@%s", nfcFL._FW_LIB_PATH.c_str());
    974 
    975   /* if library load failed then handle will be NULL */
    976   if (pFwHandle == NULL) {
    977     NXPLOG_FWDNLD_E(
    978         "NULL handler : unable to load the library file, specify correct path");
    979     return NFCSTATUS_FAILED;
    980   }
    981 
    982   dlerror(); /* Clear any existing error */
    983 
    984   /* load the address of download image pointer and image size */
    985   pImageInfo = (void*)dlsym(pFwHandle, "gphDnldNfc_DlSeq");
    986 
    987   if (dlerror() || (NULL == pImageInfo)) {
    988     NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeq");
    989     return NFCSTATUS_FAILED;
    990   }
    991   (*pImgInfo) = (*(uint8_t**)pImageInfo);
    992 
    993   pImageInfoLen = (void*)dlsym(pFwHandle, "gphDnldNfc_DlSeqSz");
    994   if (dlerror() || (NULL == pImageInfoLen)) {
    995     NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeqSz");
    996     return NFCSTATUS_FAILED;
    997   }
    998 
    999   (*pImgInfoLen) = (uint16_t)(*((uint16_t*)pImageInfoLen));
   1000 
   1001   return NFCSTATUS_SUCCESS;
   1002 }
   1003 
   1004 /*******************************************************************************
   1005 **
   1006 ** Function         phDnldNfc_LoadBinFW
   1007 **
   1008 ** Description      Load the firmware version form firmware lib
   1009 **
   1010 ** Parameters       pImgInfo    - Firmware image handle
   1011 **                  pImgInfoLen - Firmware image length
   1012 **
   1013 ** Returns          NFC status
   1014 **
   1015 *******************************************************************************/
   1016 NFCSTATUS phDnldNfc_LoadBinFW(uint8_t** pImgInfo, uint16_t* pImgInfoLen) {
   1017   FILE* pFile = NULL;
   1018   uint32_t fileSize = 0;
   1019   uint32_t bytesRead = 0;
   1020   long ftellFileSize = 0;
   1021 
   1022   /* check for path name */
   1023   if (nfcFL._FW_BIN_PATH.c_str() == NULL) {
   1024     NXPLOG_FWDNLD_E("Invalid FW file path!!!\n");
   1025     return NFCSTATUS_FAILED;
   1026   }
   1027 
   1028   /* check if the handle is not NULL then free the memory*/
   1029   if (pFwHandle != NULL) {
   1030     phDnldNfc_CloseFwLibHandle();
   1031     pFwHandle = NULL;
   1032   }
   1033 
   1034   /* Open the FW binary image file to be read */
   1035   pFile = fopen(nfcFL._FW_BIN_PATH.c_str(), "r");
   1036   if (NULL == pFile) {
   1037     NXPLOG_FWDNLD_E("Failed to load FW binary image file!!!\n");
   1038     return NFCSTATUS_FAILED;
   1039   }
   1040 
   1041   /* Seek to the end of the file */
   1042   fseek(pFile, 0, SEEK_END);
   1043 
   1044   /* get the actual length of the file */
   1045   ftellFileSize = ftell(pFile);
   1046 
   1047   if (ftellFileSize > 0) {
   1048     fileSize = ftellFileSize;
   1049   } else {
   1050     fileSize = 0;
   1051   }
   1052 
   1053   /* Seek to the start of the file, to move file handle back to start of file*/
   1054   fseek(pFile, 0, SEEK_SET);
   1055 
   1056   /* allocate the memory to read the FW binary image */
   1057   pFwHandle = (void*)malloc(sizeof(uint8_t) * fileSize);
   1058 
   1059   /* check for valid memory allocation */
   1060   if (NULL == pFwHandle) {
   1061     NXPLOG_FWDNLD_E("Failed to allocate memory to load FW image !!!\n");
   1062     fclose(pFile);
   1063     return NFCSTATUS_FAILED;
   1064   }
   1065 
   1066   /* Read the actual contents of the FW binary image */
   1067   bytesRead =
   1068       (uint32_t)fread(pFwHandle, sizeof(uint8_t), (size_t)fileSize, pFile);
   1069   if (bytesRead != fileSize) {
   1070     NXPLOG_FWDNLD_E("Unable to read the specified size from file !!!\n");
   1071     fclose(pFile);
   1072     free(pFwHandle);
   1073     pFwHandle = NULL;
   1074     return NFCSTATUS_FAILED;
   1075   }
   1076 
   1077   /* Update the image info pointer to the caller */
   1078   *pImgInfo = (uint8_t*)pFwHandle;
   1079   *pImgInfoLen = (uint16_t)(bytesRead & 0xFFFF);
   1080 
   1081   /* close the FW binary image file */
   1082   fclose(pFile);
   1083   return NFCSTATUS_SUCCESS;
   1084 }
   1085 
   1086 /*******************************************************************************
   1087 **
   1088 ** Function         phDnldNfc_LoadRecoveryFW
   1089 **
   1090 ** Description      Load the dummy firmware version form firmware lib for
   1091 **                  recovery. This will change the FW version of the NFCC
   1092 **                  firmware and enable flashing of firmware of same version.
   1093 **
   1094 ** Parameters       pImgInfo    - Firmware image handle
   1095 **                  pImgInfoLen - Firmware image length
   1096 **
   1097 ** Returns          NFCSTATUS
   1098 **
   1099 *******************************************************************************/
   1100 NFCSTATUS phDnldNfc_LoadRecoveryFW(uint8_t** pImgInfo, uint16_t* pImgInfoLen) {
   1101   void* pImageInfo = NULL;
   1102   void* pImageInfoLen = NULL;
   1103 
   1104   /* check if the handle is not NULL then free the library */
   1105   if (pFwHandle != NULL) {
   1106     phDnldNfc_CloseFwLibHandle();
   1107     pFwHandle = NULL;
   1108   }
   1109   /* load the DLL file */
   1110   pFwHandle = dlopen(nfcFL._FW_LIB_PATH.c_str(), RTLD_LAZY);
   1111   NXPLOG_FWDNLD_D("phDnldNfc_LoadRecoveryFW %s ", nfcFL._FW_LIB_PATH.c_str());
   1112 
   1113   /* if library load failed then handle will be NULL */
   1114   if (pFwHandle == NULL) {
   1115     NXPLOG_FWDNLD_E(
   1116         "NULL handler : unable to load the library file, specify correct path");
   1117     return NFCSTATUS_FAILED;
   1118   }
   1119 
   1120   dlerror(); /* Clear any existing error */
   1121 
   1122   /* load the address of download image pointer and image size */
   1123   pImageInfo = (void*)dlsym(pFwHandle, "gphDnldNfc_DummyDlSeq");
   1124 
   1125   if (dlerror() || (NULL == pImageInfo)) {
   1126     NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DummyDlSeq");
   1127     return NFCSTATUS_FAILED;
   1128   }
   1129 
   1130   (*pImgInfo) = (*(uint8_t**)pImageInfo);
   1131   pImageInfoLen = (void*)dlsym(pFwHandle, "gphDnldNfc_DlSeqDummyFwSz");
   1132   if (dlerror() || (NULL == pImageInfoLen)) {
   1133     NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeqDummyFwSz");
   1134     return NFCSTATUS_FAILED;
   1135   }
   1136 
   1137   (*pImgInfoLen) = (uint16_t)(*((uint16_t*)pImageInfoLen));
   1138 
   1139   return NFCSTATUS_SUCCESS;
   1140 }
   1141 
   1142 /*******************************************************************************
   1143 **
   1144 ** Function         phDnldNfc_UnloadFW
   1145 **
   1146 ** Description      Deinit the firmware handle
   1147 **
   1148 ** Parameters       None
   1149 **
   1150 ** Returns          NFC status
   1151 **
   1152 *******************************************************************************/
   1153 NFCSTATUS phDnldNfc_UnloadFW(void) {
   1154   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1155   int32_t status;
   1156 
   1157   /* check if the handle is not NULL then free the library */
   1158   if (pFwHandle != NULL) {
   1159     status = dlclose(pFwHandle);
   1160     pFwHandle = NULL;
   1161 
   1162     dlerror(); /* Clear any existing error */
   1163     if (status != 0) {
   1164       wStatus = NFCSTATUS_FAILED;
   1165       NXPLOG_FWDNLD_E("Free library file failed");
   1166     }
   1167   }
   1168 
   1169   return wStatus;
   1170 }
   1171 
   1172 #ifdef EEPROM_Read_Mem_IMP
   1173 static pphDnldNfc_RspCb_t UserCb; /* Upper layer call back function */
   1174 static void* UserCtxt;            /* Pointer to upper layer context */
   1175 /* Function prototype declaration */
   1176 static void phDnldNfc_ReadComplete(void* pContext, NFCSTATUS status,
   1177                                    void* pInfo);
   1178 
   1179 /*******************************************************************************
   1180 **
   1181 ** Function         phDnldNfc_ReadMem
   1182 **
   1183 ** Description      Dumps the contents of EEPROM. The handle is required for
   1184 **                  subsequent operations
   1185 **
   1186 ** Parameters       pHwRef - pointer to the hardware device
   1187 **                  pNotify - notify caller after getting response
   1188 **                  pContext - caller context
   1189 **
   1190 ** Returns          NFC status:
   1191 **                  NFCSTATUS_SUCCESS - request to NFCC is successful
   1192 **                  NFCSTATUS_FAILED - request failed due to internal error
   1193 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
   1194 **                  Other command specific errors
   1195 **
   1196 *******************************************************************************/
   1197 NFCSTATUS phDnldNfc_ReadMem(void* pHwRef, pphDnldNfc_RspCb_t pNotify,
   1198                             void* pContext) {
   1199   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1200   uint32_t wAddr = 0x2011C0; /* eeprom platform specific area start address */
   1201   uint32_t wRdAddr = 0;
   1202   uint8_t* pAddr;
   1203   static uint8_t bRdData[3519]; /* buffer to hold the read data */
   1204   static phDnldNfc_Buff_t Data;
   1205 
   1206   if ((NULL == pNotify) || (NULL == pContext)) {
   1207     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
   1208     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
   1209   } else {
   1210     /* Call Tml Ioctl to enable download mode */
   1211     wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
   1212 
   1213     if (NFCSTATUS_SUCCESS == wStatus) {
   1214       /* Set the obtained device handle to download module */
   1215       phDnldNfc_SetHwDevHandle();
   1216     } else {
   1217       wStatus = NFCSTATUS_FAILED;
   1218     }
   1219 
   1220     if (NFCSTATUS_SUCCESS == wStatus) {
   1221       pAddr = (uint8_t*)&wAddr;
   1222 
   1223       wRdAddr = (pAddr[3]);
   1224       wRdAddr <<= 8;
   1225       wRdAddr |= (pAddr[2]);
   1226       wRdAddr <<= 8;
   1227       wRdAddr |= (pAddr[1]);
   1228       wRdAddr <<= 8;
   1229       wRdAddr |= (pAddr[0]);
   1230 
   1231       Data.pBuff = bRdData;
   1232       Data.wLen = sizeof(bRdData);
   1233       UserCb = pNotify;
   1234       UserCtxt = pContext;
   1235 
   1236       wStatus = phDnldNfc_Read(&Data, wRdAddr,
   1237                                (pphDnldNfc_RspCb_t)phDnldNfc_ReadComplete,
   1238                                gpphDnldContext);
   1239     } else {
   1240       Data.pBuff = NULL;
   1241       Data.wLen = 0;
   1242       wStatus = NFCSTATUS_FAILED;
   1243     }
   1244 
   1245     if (NFCSTATUS_PENDING == wStatus) {
   1246       NXPLOG_FWDNLD_D("Read Request submitted successfully..");
   1247     } else {
   1248       NXPLOG_FWDNLD_E("Read Request submission failed!!");
   1249     }
   1250   }
   1251 
   1252   return wStatus;
   1253 }
   1254 
   1255 /*******************************************************************************
   1256 **
   1257 ** Function         phDnldNfc_ReadComplete
   1258 **
   1259 ** Description      Read complete
   1260 **
   1261 ** Parameters       pContext - caller layer context
   1262 **                  status   - status of the transaction
   1263 **                  pInfo    - transaction info
   1264 **
   1265 ** Returns          None
   1266 **
   1267 *******************************************************************************/
   1268 static void phDnldNfc_ReadComplete(void* pContext, NFCSTATUS status,
   1269                                    void* pInfo) {
   1270   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1271   UNUSED(pContext);
   1272 
   1273   /* Call Tml Ioctl to enable/restore normal mode */
   1274   wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
   1275 
   1276   if (NFCSTATUS_SUCCESS == wStatus) {
   1277     NXPLOG_FWDNLD_D("Read Done!!");
   1278   }
   1279 
   1280   UserCb(&UserCtxt, status, pInfo);
   1281 
   1282   return;
   1283 }
   1284 
   1285 /*******************************************************************************
   1286 **
   1287 ** Function         phDnldNfc_Read
   1288 **
   1289 ** Description      Retrieves requested data of specified length from desired
   1290 **                  EEPROM address
   1291 **
   1292 ** Parameters       pData - response buffer which gets updated with data from
   1293 **                          EEPROM
   1294 **                  dwRdAddr - EEPROM address for data read
   1295 **                  pNotify - notify caller after getting response
   1296 **                  pContext - caller context
   1297 **
   1298 ** Returns          NFC status:
   1299 **                  NFCSTATUS_SUCCESS - Read request to NFCC is successful
   1300 **                  NFCSTATUS_FAILED - Read request failed due to internal error
   1301 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
   1302 **                  Other command specific errors
   1303 **
   1304 *******************************************************************************/
   1305 NFCSTATUS phDnldNfc_Read(pphDnldNfc_Buff_t pData, uint32_t dwRdAddr,
   1306                          pphDnldNfc_RspCb_t pNotify, void* pContext) {
   1307   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1308 
   1309   if ((NULL == pNotify) || (NULL == pData) || (NULL == pContext)) {
   1310     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
   1311     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
   1312   } else {
   1313     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
   1314       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
   1315       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
   1316     } else {
   1317       if ((NULL != pData->pBuff) && (0 != pData->wLen)) {
   1318         (gpphDnldContext->tCmdId) = PH_DL_CMD_READ;
   1319         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRead;
   1320         (gpphDnldContext->FrameInp.dwAddr) = dwRdAddr;
   1321         (gpphDnldContext->tRspBuffInfo.pBuff) = pData->pBuff;
   1322         (gpphDnldContext->tRspBuffInfo.wLen) = pData->wLen;
   1323         (gpphDnldContext->tUserData.pBuff) = NULL;
   1324         (gpphDnldContext->tUserData.wLen) = 0;
   1325         (gpphDnldContext->UserCb) = pNotify;
   1326         (gpphDnldContext->UserCtxt) = pContext;
   1327 
   1328         memset(&(gpphDnldContext->tRWInfo), 0,
   1329                sizeof(gpphDnldContext->tRWInfo));
   1330 
   1331         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventRead);
   1332 
   1333         if (NFCSTATUS_PENDING == wStatus) {
   1334           NXPLOG_FWDNLD_D("Read Request submitted successfully");
   1335         } else {
   1336           NXPLOG_FWDNLD_E("Read Request Failed!!");
   1337         }
   1338       } else {
   1339         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
   1340         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
   1341       }
   1342     }
   1343   }
   1344 
   1345   return wStatus;
   1346 }
   1347 #endif
   1348