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  * Internal Download Management routines
     19  * Download Component
     20  */
     21 
     22 #include <phDnldNfc_Internal.h>
     23 #include <phDnldNfc_Utils.h>
     24 #include <phTmlNfc.h>
     25 #include <phNxpLog.h>
     26 #include <phNxpNciHal_utils.h>
     27 
     28 #define PHDNLDNFC_MIN_PLD_LEN   (0x04U)                      /* Minimum length of payload including 1 byte CmdId */
     29 
     30 #define PHDNLDNFC_FRAME_HDR_OFFSET  (0x00)                    /* Offset of Length byte within the frame */
     31 #define PHDNLDNFC_FRAMEID_OFFSET (PHDNLDNFC_FRAME_HDR_LEN)        /* Offset of FrameId within the frame */
     32 #define PHDNLDNFC_FRAMESTATUS_OFFSET PHDNLDNFC_FRAMEID_OFFSET  /* Offset of status byte within the frame */
     33 #define PHDNLDNFC_PLD_OFFSET    (PHDNLDNFC_MIN_PLD_LEN - 1)    /* Offset within frame where payload starts*/
     34 
     35 #define PHDNLDNFC_FRAME_RDDATA_OFFSET ((PHDNLDNFC_FRAME_HDR_LEN) + \
     36                                       (PHDNLDNFC_MIN_PLD_LEN)) /* recvd frame offset where data starts */
     37 
     38 #define PHDNLDNFC_FRAME_SIGNATURE_SIZE   (0xC0U)        /* Size of first secure write frame Signature */
     39 #define PHDNLDNFC_FIRST_FRAME_PLD_SIZE   (0xE4U)        /* Size of first secure write frame payload */
     40 
     41 #define PHDNLDNFC_FIRST_FRAGFRAME_RESP   (0x2DU)        /* Status response for first fragmented write frame */
     42 #define PHDNLDNFC_NEXT_FRAGFRAME_RESP    (0x2EU)        /* Status response for subsequent fragmented write frame */
     43 
     44 #define PHDNLDNFC_SET_HDR_FRAGBIT(n)      ((n) | (1<<10))    /* Header chunk bit set macro */
     45 #define PHDNLDNFC_CLR_HDR_FRAGBIT(n)      ((n) & ~(1U<<10))   /* Header chunk bit clear macro */
     46 #define PHDNLDNFC_CHK_HDR_FRAGBIT(n)      ((n) & 0x04)       /* macro to check if frag bit is set in Hdr */
     47 
     48 #define PHDNLDNFC_RSP_TIMEOUT   (2500)                /* Timeout value to wait for response from NFCC */
     49 #define PHDNLDNFC_RETRY_FRAME_WRITE   (50)            /* Timeout value to wait before resending the last frame */
     50 
     51 #define PHDNLDNFC_USERDATA_EEPROM_LENSIZE    (0x02U)    /* size of EEPROM user data length */
     52 #define PHDNLDNFC_USERDATA_EEPROM_OFFSIZE    (0x02U)    /* size of EEPROM offset */
     53 
     54 #ifdef  NXP_PN547C1_DOWNLOAD
     55 /* EEPROM offset and length value for PN547C1 */
     56 #define PHDNLDNFC_USERDATA_EEPROM_OFFSET  (0x003CU)    /* 16 bits offset indicating user data area start location */
     57 #define PHDNLDNFC_USERDATA_EEPROM_LEN     (0x0DC0U)    /* 16 bits length of user data area */
     58 #else
     59 
     60 #if(NFC_NXP_CHIP_TYPE == PN548C2)
     61 /* EEPROM offset and length value for PN548AD */
     62 #define PHDNLDNFC_USERDATA_EEPROM_OFFSET  (0x02BCU)    /* 16 bits offset indicating user data area start location */
     63 #define PHDNLDNFC_USERDATA_EEPROM_LEN     (0x0C00U)    /* 16 bits length of user data area */
     64 #elif(NFC_NXP_CHIP_TYPE == PN551)
     65 /* EEPROM offset and length value for PN551 */
     66 #define PHDNLDNFC_USERDATA_EEPROM_OFFSET  (0x02BCU)    /* 16 bits offset indicating user data area start location */
     67 #define PHDNLDNFC_USERDATA_EEPROM_LEN     (0x0C00U)    /* 16 bits length of user data area */
     68 #else
     69 /* EEPROM offset and length value for PN547C2 */
     70 #define PHDNLDNFC_USERDATA_EEPROM_OFFSET  (0x023CU)    /* 16 bits offset indicating user data area start location */
     71 #define PHDNLDNFC_USERDATA_EEPROM_LEN     (0x0C80U)    /* 16 bits length of user data area */
     72 #endif
     73 
     74 #endif
     75 #define PH_LIBNFC_VEN_RESET_ON_DOWNLOAD_TIMEOUT (1)
     76 
     77 /* Function prototype declarations */
     78 static void phDnldNfc_ProcessSeqState(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
     79 static void phDnldNfc_ProcessRWSeqState(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
     80 static NFCSTATUS phDnldNfc_ProcessFrame(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
     81 static NFCSTATUS phDnldNfc_ProcessRecvInfo(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
     82 static NFCSTATUS phDnldNfc_BuildFramePkt(pphDnldNfc_DlContext_t pDlContext);
     83 static NFCSTATUS phDnldNfc_CreateFramePld(pphDnldNfc_DlContext_t pDlContext);
     84 static NFCSTATUS phDnldNfc_SetupResendTimer(pphDnldNfc_DlContext_t pDlContext);
     85 static NFCSTATUS phDnldNfc_UpdateRsp(pphDnldNfc_DlContext_t   pDlContext, phTmlNfc_TransactInfo_t  *pInfo, uint16_t wPldLen);
     86 static void phDnldNfc_RspTimeOutCb(uint32_t TimerId, void *pContext);
     87 static void phDnldNfc_ResendTimeOutCb(uint32_t TimerId, void *pContext);
     88 
     89 /*
     90 *************************** Function Definitions ***************************
     91 */
     92 
     93 /*******************************************************************************
     94 **
     95 ** Function         phDnldNfc_CmdHandler
     96 **
     97 ** Description      Download Command Handler Mechanism
     98 **                  - holds the sub states for each command processing
     99 **                  - coordinates with TML download thread to complete a download command request
    100 **                  - calls the user callback on completion of a cmd
    101 **
    102 ** Parameters       pContext  - pointer to the download context structure
    103 **                  TrigEvent - event requested by user
    104 **
    105 ** Returns          NFC status:
    106 **                  NFCSTATUS_PENDING           - download request sent to NFCC successfully,response pending
    107 **                  NFCSTATUS_BUSY              - handler is busy processing a download request
    108 **                  NFCSTATUS_INVALID_PARAMETER - one or more of the supplied parameters could not be interpreted properly
    109 **                  Other errors                -
    110 **
    111 *******************************************************************************/
    112 NFCSTATUS phDnldNfc_CmdHandler(void *pContext, phDnldNfc_Event_t TrigEvent)
    113 {
    114     NFCSTATUS  status = NFCSTATUS_SUCCESS;
    115     pphDnldNfc_DlContext_t  pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
    116 
    117     if(NULL == pDlCtxt)
    118     {
    119       NXPLOG_FWDNLD_E("Invalid Input Parameter!!");
    120       status = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
    121     }
    122     else
    123     {
    124         switch(TrigEvent)
    125         {
    126             case phDnldNfc_EventReset:
    127             case phDnldNfc_EventGetVer:
    128             case phDnldNfc_EventIntegChk:
    129             case phDnldNfc_EventGetSesnSt:
    130             case phDnldNfc_EventRaw:
    131             {
    132                 if(phDnldNfc_EventInvalid == (pDlCtxt->tCurrEvent))
    133                 {
    134                     NXPLOG_FWDNLD_D("Processing Normal Sequence..");
    135                     pDlCtxt->tCurrEvent = TrigEvent;
    136                     pDlCtxt->tDnldInProgress = phDnldNfc_TransitionBusy;
    137 
    138                     phDnldNfc_ProcessSeqState(pDlCtxt,NULL);
    139 
    140                     status = pDlCtxt->wCmdSendStatus;
    141                 }
    142                 else
    143                 {
    144                     NXPLOG_FWDNLD_E("Prev Norml Sequence not completed/restored!!");
    145                     status = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
    146                 }
    147                 break;
    148             }
    149             case phDnldNfc_EventWrite:
    150             case phDnldNfc_EventRead:
    151             case phDnldNfc_EventLog:
    152             case phDnldNfc_EventForce:
    153             {
    154                 if(phDnldNfc_EventInvalid == (pDlCtxt->tCurrEvent))
    155                 {
    156                     NXPLOG_FWDNLD_D("Processing R/W Sequence..");
    157                     pDlCtxt->tCurrEvent = TrigEvent;
    158                     pDlCtxt->tDnldInProgress = phDnldNfc_TransitionBusy;
    159 
    160                     phDnldNfc_ProcessRWSeqState(pDlCtxt,NULL);
    161 
    162                     status = pDlCtxt->wCmdSendStatus;
    163                 }
    164                 else
    165                 {
    166                     NXPLOG_FWDNLD_E("Prev R/W Sequence not completed/restored!!");
    167                     status = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
    168                 }
    169                 break;
    170             }
    171             default:
    172             {
    173                 /* Unknown Event */
    174                 NXPLOG_FWDNLD_E("Unknown Event Parameter!!");
    175                 status = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
    176                 break;
    177             }
    178         }
    179     }
    180 
    181     return status;
    182 }
    183 
    184 /*******************************************************************************
    185 **
    186 ** Function         phDnldNfc_ProcessSeqState
    187 **
    188 ** Description      Processes all cmd/resp sequences except read & write
    189 **
    190 ** Parameters       pContext - pointer to the download context structure
    191 **                  pInfo    - pointer to the Transaction buffer updated by TML Thread
    192 **
    193 ** Returns          None
    194 **
    195 *******************************************************************************/
    196 static void phDnldNfc_ProcessSeqState(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
    197 {
    198     NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    199     NFCSTATUS wIntStatus;
    200     uint32_t TimerId;
    201     pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
    202 
    203     if(NULL == pDlCtxt)
    204     {
    205         NXPLOG_FWDNLD_E("Invalid Input Parameter!!");
    206         wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
    207     }
    208     else
    209     {
    210         switch(pDlCtxt->tCurrState)
    211         {
    212             case phDnldNfc_StateInit:
    213             {
    214                 NXPLOG_FWDNLD_D("Initializing Sequence..");
    215 
    216                 if(0 == (pDlCtxt->TimerInfo.dwRspTimerId))
    217                 {
    218                     TimerId = phOsalNfc_Timer_Create();
    219 
    220                     if (0 == TimerId)
    221                     {
    222                         NXPLOG_FWDNLD_W("Response Timer Create failed!!");
    223                         wStatus = NFCSTATUS_INSUFFICIENT_RESOURCES;
    224                         pDlCtxt->wCmdSendStatus = wStatus;
    225                         break;
    226                     }
    227                     else
    228                     {
    229                         NXPLOG_FWDNLD_D("Response Timer Created Successfully");
    230                         (pDlCtxt->TimerInfo.dwRspTimerId) = TimerId;
    231                         (pDlCtxt->TimerInfo.TimerStatus) = 0;
    232                         (pDlCtxt->TimerInfo.wTimerExpStatus) = 0;
    233                     }
    234                 }
    235                 pDlCtxt->tCurrState = phDnldNfc_StateSend;
    236             }
    237             case phDnldNfc_StateSend:
    238             {
    239                 wStatus = phDnldNfc_BuildFramePkt(pDlCtxt);
    240 
    241                 if(NFCSTATUS_SUCCESS == wStatus)
    242                 {
    243                     pDlCtxt->tCurrState = phDnldNfc_StateRecv;
    244 
    245                     wStatus = phTmlNfc_Write( (pDlCtxt->tCmdRspFrameInfo.aFrameBuff),
    246                         (uint16_t)(pDlCtxt->tCmdRspFrameInfo.dwSendlength),
    247                                     (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessSeqState,
    248                                     pDlCtxt);
    249                 }
    250                 pDlCtxt->wCmdSendStatus = wStatus;
    251                 break;
    252             }
    253             case phDnldNfc_StateRecv:
    254             {
    255                 wStatus = phDnldNfc_ProcessRecvInfo(pContext,pInfo);
    256 
    257                 if(NFCSTATUS_SUCCESS == wStatus)
    258                 {
    259                     wStatus = phOsalNfc_Timer_Start((pDlCtxt->TimerInfo.dwRspTimerId),
    260                                                 PHDNLDNFC_RSP_TIMEOUT,
    261                                                 &phDnldNfc_RspTimeOutCb,
    262                                                 pDlCtxt);
    263 
    264                     if (NFCSTATUS_SUCCESS == wStatus)
    265                     {
    266                         NXPLOG_FWDNLD_D("Response timer started");
    267                         pDlCtxt->TimerInfo.TimerStatus = 1;
    268                         pDlCtxt->tCurrState = phDnldNfc_StateTimer;
    269                     }
    270                     else
    271                     {
    272                          NXPLOG_FWDNLD_W("Response timer not started");
    273                         pDlCtxt->tCurrState = phDnldNfc_StateResponse;
    274                     }
    275                     /* Call TML_Read function and register the call back function */
    276                     wStatus = phTmlNfc_Read(
    277                         pDlCtxt->tCmdRspFrameInfo.aFrameBuff,
    278                         (uint16_t )PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE,
    279                         (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessSeqState,
    280                         (void *)pDlCtxt);
    281 
    282                     /* set read status to pDlCtxt->wCmdSendStatus to enable callback */
    283                     pDlCtxt->wCmdSendStatus = wStatus;
    284                     break;
    285                 }
    286                 else
    287                 {
    288                     /* Setting TimerExpStatus below to avoid frame processing in response state */
    289                     (pDlCtxt->TimerInfo.wTimerExpStatus) = NFCSTATUS_RF_TIMEOUT;
    290                     pDlCtxt->tCurrState = phDnldNfc_StateResponse;
    291                 }
    292             }
    293             case phDnldNfc_StateTimer:
    294             {
    295                 if (1 == (pDlCtxt->TimerInfo.TimerStatus)) /*Is Timer Running*/
    296                 {
    297                     /*Stop Timer*/
    298                     (void)phOsalNfc_Timer_Stop(pDlCtxt->TimerInfo.dwRspTimerId);
    299                     (pDlCtxt->TimerInfo.TimerStatus) = 0; /*timer stopped*/
    300                 }
    301                 pDlCtxt->tCurrState = phDnldNfc_StateResponse;
    302             }
    303             case phDnldNfc_StateResponse:
    304             {
    305                 if(NFCSTATUS_RF_TIMEOUT != (pDlCtxt->TimerInfo.wTimerExpStatus))
    306                 {
    307                     /* Process response */
    308                     wStatus = phDnldNfc_ProcessFrame(pContext,pInfo);
    309                 }
    310                 else
    311                 {
    312                     if(phDnldNfc_EventReset != pDlCtxt->tCurrEvent)
    313                     {
    314                         wStatus = (pDlCtxt->TimerInfo.wTimerExpStatus);
    315                     }
    316                     else
    317                     {
    318                         wStatus = NFCSTATUS_SUCCESS;
    319                     }
    320                     (pDlCtxt->TimerInfo.wTimerExpStatus) = 0;
    321                 }
    322 
    323                 /* Abort TML read operation which is always kept open */
    324                 wIntStatus  = phTmlNfc_ReadAbort();
    325 
    326                 if(NFCSTATUS_SUCCESS != wIntStatus)
    327                 {
    328                     /* TODO:-Action to take in this case:-Tml read abort failed!? */
    329                     NXPLOG_FWDNLD_W("Tml Read Abort failed!!");
    330                 }
    331 
    332                 pDlCtxt->tCurrEvent = phDnldNfc_EventInvalid;
    333                 pDlCtxt->tDnldInProgress = phDnldNfc_TransitionIdle;
    334                 pDlCtxt->tCurrState = phDnldNfc_StateInit;
    335 
    336                 /* Delete the timer & reset timer primitives in context */
    337                 (void)phOsalNfc_Timer_Delete(pDlCtxt->TimerInfo.dwRspTimerId);
    338                 (pDlCtxt->TimerInfo.dwRspTimerId) = 0;
    339                 (pDlCtxt->TimerInfo.TimerStatus) = 0;
    340                 (pDlCtxt->TimerInfo.wTimerExpStatus) = 0;
    341 
    342                 if((NULL != (pDlCtxt->UserCb)) && (NULL != (pDlCtxt->UserCtxt)))
    343                 {
    344                     pDlCtxt->UserCb((pDlCtxt->UserCtxt),wStatus,&(pDlCtxt->tRspBuffInfo));
    345                 }
    346                 break;
    347             }
    348             default:
    349             {
    350                 pDlCtxt->tCurrEvent = phDnldNfc_EventInvalid;
    351                 pDlCtxt->tDnldInProgress = phDnldNfc_TransitionIdle;
    352                 break;
    353             }
    354         }
    355     }
    356 
    357     return;
    358 }
    359 
    360 /*******************************************************************************
    361 **
    362 ** Function         phDnldNfc_ProcessRWSeqState
    363 **
    364 ** Description      Processes read/write cmd/rsp sequence
    365 **
    366 ** Parameters       pContext - pointer to the download context structure
    367 **                  pInfo    - pointer to the Transaction buffer updated by TML Thread
    368 **
    369 ** Returns          None
    370 **
    371 *******************************************************************************/
    372 static void phDnldNfc_ProcessRWSeqState(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
    373 {
    374     NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    375     NFCSTATUS wIntStatus = wStatus;
    376     uint32_t TimerId;
    377     pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
    378 
    379     if(NULL == pDlCtxt)
    380     {
    381         NXPLOG_FWDNLD_E("Invalid Input Parameter!!");
    382         wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
    383     }
    384     else
    385     {
    386         switch(pDlCtxt->tCurrState)
    387         {
    388             case phDnldNfc_StateInit:
    389             {
    390                 if(0 == (pDlCtxt->TimerInfo.dwRspTimerId))
    391                 {
    392                     TimerId = phOsalNfc_Timer_Create();
    393 
    394                     if (0 == TimerId)
    395                     {
    396                         NXPLOG_FWDNLD_E("Response Timer Create failed!!");
    397                         wStatus = NFCSTATUS_INSUFFICIENT_RESOURCES;
    398                     }
    399                     else
    400                     {
    401                         NXPLOG_FWDNLD_D("Response Timer Created Successfully");
    402                         (pDlCtxt->TimerInfo.dwRspTimerId) = TimerId;
    403                         (pDlCtxt->TimerInfo.TimerStatus) = 0;
    404                         (pDlCtxt->TimerInfo.wTimerExpStatus) = 0;
    405                     }
    406                 }
    407                 pDlCtxt->tCurrState = phDnldNfc_StateSend;
    408             }
    409             case phDnldNfc_StateSend:
    410             {
    411                 if(FALSE == pDlCtxt->bResendLastFrame)
    412                 {
    413                     wStatus = phDnldNfc_BuildFramePkt(pDlCtxt);
    414                 }
    415                 else
    416                 {
    417                     pDlCtxt->bResendLastFrame = FALSE;
    418                 }
    419 
    420                 if(NFCSTATUS_SUCCESS == wStatus)
    421                 {
    422                     pDlCtxt->tCurrState = phDnldNfc_StateRecv;
    423 
    424                     wStatus = phTmlNfc_Write((pDlCtxt->tCmdRspFrameInfo.aFrameBuff),
    425                         (uint16_t)(pDlCtxt->tCmdRspFrameInfo.dwSendlength),
    426                                     (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessRWSeqState,
    427                                     pDlCtxt);
    428                 }
    429                 pDlCtxt->wCmdSendStatus = wStatus;
    430                 break;
    431             }
    432             case phDnldNfc_StateRecv:
    433             {
    434                 wStatus = phDnldNfc_ProcessRecvInfo(pContext,pInfo);
    435 
    436                 if(NFCSTATUS_SUCCESS == wStatus)
    437                 {
    438                     /* processing For Pipelined write before calling timer below */
    439                     wStatus = phOsalNfc_Timer_Start((pDlCtxt->TimerInfo.dwRspTimerId),
    440                                                 PHDNLDNFC_RSP_TIMEOUT,
    441                                                 &phDnldNfc_RspTimeOutCb,
    442                                                 pDlCtxt);
    443 
    444                     if (NFCSTATUS_SUCCESS == wStatus)
    445                     {
    446                         NXPLOG_FWDNLD_D("Response timer started");
    447                         pDlCtxt->TimerInfo.TimerStatus = 1;
    448                         pDlCtxt->tCurrState = phDnldNfc_StateTimer;
    449                     }
    450                     else
    451                     {
    452                          NXPLOG_FWDNLD_W("Response timer not started");
    453                         pDlCtxt->tCurrState = phDnldNfc_StateResponse;
    454                         /* Todo:- diagnostic in this case */
    455                     }
    456                     /* Call TML_Read function and register the call back function */
    457                     wStatus = phTmlNfc_Read(
    458                         pDlCtxt->tCmdRspFrameInfo.aFrameBuff,
    459                         (uint16_t )PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE,
    460                         (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessRWSeqState,
    461                         (void *)pDlCtxt);
    462 
    463                     /* set read status to pDlCtxt->wCmdSendStatus to enable callback */
    464                     pDlCtxt->wCmdSendStatus = wStatus;
    465                     break;
    466                 }
    467                 else
    468                 {
    469                     /* Setting TimerExpStatus below to avoid frame processing in reponse state */
    470                     (pDlCtxt->TimerInfo.wTimerExpStatus) = NFCSTATUS_RF_TIMEOUT;
    471                     pDlCtxt->tCurrState = phDnldNfc_StateResponse;
    472                 }
    473             }
    474             case phDnldNfc_StateTimer:
    475             {
    476                 if (1 == (pDlCtxt->TimerInfo.TimerStatus)) /*Is Timer Running*/
    477                 {
    478                     /* Stop Timer */
    479                     (void)phOsalNfc_Timer_Stop(pDlCtxt->TimerInfo.dwRspTimerId);
    480                     (pDlCtxt->TimerInfo.TimerStatus) = 0; /*timer stopped*/
    481                 }
    482                 pDlCtxt->tCurrState = phDnldNfc_StateResponse;
    483             }
    484             case phDnldNfc_StateResponse:
    485             {
    486                 if(NFCSTATUS_RF_TIMEOUT != (pDlCtxt->TimerInfo.wTimerExpStatus))
    487                 {
    488                     /* Process response */
    489                     wStatus = phDnldNfc_ProcessFrame(pContext,pInfo);
    490 
    491                     if(NFCSTATUS_BUSY == wStatus)
    492                     {
    493                         /* store the status for use in subsequent processing */
    494                         wIntStatus = wStatus;
    495 
    496                         /* setup the resend wait timer */
    497                         wStatus = phDnldNfc_SetupResendTimer(pDlCtxt);
    498 
    499                         if(NFCSTATUS_SUCCESS == wStatus)
    500                         {
    501                             /* restore the last mem_bsy status to avoid re-building frame below */
    502                             wStatus = wIntStatus;
    503                         }
    504                     }
    505                 }
    506                 else
    507                 {
    508                     wStatus = (pDlCtxt->TimerInfo.wTimerExpStatus);
    509                     (pDlCtxt->TimerInfo.wTimerExpStatus) = 0;
    510                 }
    511 
    512                 if((0 != (pDlCtxt->tRWInfo.wRemBytes)) && (NFCSTATUS_SUCCESS == wStatus))
    513                 {
    514                     /* Abort TML read operation which is always kept open */
    515                     wIntStatus  = phTmlNfc_ReadAbort();
    516 
    517                     if(NFCSTATUS_SUCCESS != wIntStatus)
    518                     {
    519                          NXPLOG_FWDNLD_W("Tml read abort failed!");
    520                     }
    521 
    522                     wStatus = phDnldNfc_BuildFramePkt(pDlCtxt);
    523 
    524                     if(NFCSTATUS_SUCCESS == wStatus)
    525                     {
    526                         pDlCtxt->tCurrState = phDnldNfc_StateRecv;
    527                         wStatus = phTmlNfc_Write((pDlCtxt->tCmdRspFrameInfo.aFrameBuff),
    528                             (uint16_t)(pDlCtxt->tCmdRspFrameInfo.dwSendlength),
    529                                         (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessRWSeqState,
    530                                         pDlCtxt);
    531 
    532                         /* TODO:- Verify here if TML_Write returned NFC_PENDING status & take appropriate
    533                               action otherwise ?? */
    534                     }
    535                 }
    536                 else if(NFCSTATUS_BUSY == wStatus)
    537                 {
    538                     /* No processing to be done,since resend wait timer should have already been started */
    539                 }
    540                 else
    541                 {
    542                     (pDlCtxt->tRWInfo.bFramesSegmented) = FALSE;
    543                     /* Abort TML read operation which is always kept open */
    544                     wIntStatus  = phTmlNfc_ReadAbort();
    545 
    546                     if(NFCSTATUS_SUCCESS != wIntStatus)
    547                     {
    548                          NXPLOG_FWDNLD_W("Tml read abort failed!");
    549                     }
    550 
    551                     pDlCtxt->tCurrEvent = phDnldNfc_EventInvalid;
    552                     pDlCtxt->tDnldInProgress = phDnldNfc_TransitionIdle;
    553                     pDlCtxt->tCurrState = phDnldNfc_StateInit;
    554                     pDlCtxt->bResendLastFrame = FALSE;
    555 
    556                     /* Delete the timer & reset timer primitives in context */
    557                     (void)phOsalNfc_Timer_Delete(pDlCtxt->TimerInfo.dwRspTimerId);
    558                     (pDlCtxt->TimerInfo.dwRspTimerId) = 0;
    559                     (pDlCtxt->TimerInfo.TimerStatus) = 0;
    560                     (pDlCtxt->TimerInfo.wTimerExpStatus) = 0;
    561 
    562                     if((NULL != (pDlCtxt->UserCb)) && (NULL != (pDlCtxt->UserCtxt)))
    563                     {
    564                         pDlCtxt->UserCb((pDlCtxt->UserCtxt),wStatus,&(pDlCtxt->tRspBuffInfo));
    565                     }
    566                 }
    567                 break;
    568             }
    569             default:
    570             {
    571                 pDlCtxt->tCurrEvent = phDnldNfc_EventInvalid;
    572                 pDlCtxt->tDnldInProgress = phDnldNfc_TransitionIdle;
    573                 break;
    574             }
    575         }
    576     }
    577 
    578     return;
    579 }
    580 
    581 /*******************************************************************************
    582 **
    583 ** Function         phDnldNfc_BuildFramePkt
    584 **
    585 ** Description      Forms the frame packet
    586 **
    587 ** Parameters       pDlContext - pointer to the download context structure
    588 **
    589 ** Returns          NFC status
    590 **
    591 *******************************************************************************/
    592 static NFCSTATUS phDnldNfc_BuildFramePkt(pphDnldNfc_DlContext_t pDlContext)
    593 {
    594     NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    595     uint16_t wFrameLen = 0;
    596     uint16_t wCrcVal;
    597     uint8_t *pFrameByte;
    598 
    599     if(NULL == pDlContext)
    600     {
    601         NXPLOG_FWDNLD_E("Invalid Input Parameter!!");
    602         wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
    603     }
    604     else
    605     {
    606         if(phDnldNfc_FTWrite == (pDlContext->FrameInp.Type))
    607         {
    608             if((0 == (pDlContext->tUserData.wLen)) || (NULL == (pDlContext->tUserData.pBuff)))
    609             {
    610                 NXPLOG_FWDNLD_E("Invalid Input Parameter(s) for Write!!");
    611                 wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
    612             }
    613             else
    614             {
    615                 if(TRUE == (pDlContext->tRWInfo.bFirstWrReq))
    616                 {
    617                     (pDlContext->tRWInfo.wRemBytes) = (pDlContext->tUserData.wLen);
    618                     (pDlContext->tRWInfo.wOffset) = 0;
    619                 }
    620             }
    621         }
    622         else if(phDnldNfc_FTRead == (pDlContext->FrameInp.Type))
    623         {
    624             if((0 == (pDlContext->tRspBuffInfo.wLen)) || (NULL == (pDlContext->tRspBuffInfo.pBuff)))
    625             {
    626                 NXPLOG_FWDNLD_E("Invalid Input Parameter(s) for Read!!");
    627                 wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
    628             }
    629             else
    630             {
    631                 if(FALSE == (pDlContext->tRWInfo.bFramesSegmented))
    632                 {
    633                     NXPLOG_FWDNLD_D("Verifying RspBuffInfo for Read Request..");
    634                     wFrameLen = (pDlContext->tRspBuffInfo.wLen) + PHDNLDNFC_MIN_PLD_LEN;
    635 
    636                     (pDlContext->tRWInfo.wRWPldSize) = (PHDNLDNFC_CMDRESP_MAX_PLD_SIZE - PHDNLDNFC_MIN_PLD_LEN);
    637                     (pDlContext->tRWInfo.wRemBytes) = (pDlContext->tRspBuffInfo.wLen);
    638                     (pDlContext->tRWInfo.dwAddr) = (pDlContext->FrameInp.dwAddr);
    639                     (pDlContext->tRWInfo.wOffset) = 0;
    640                     (pDlContext->tRWInfo.wBytesRead) = 0;
    641 
    642                     if(PHDNLDNFC_CMDRESP_MAX_PLD_SIZE < wFrameLen)
    643                     {
    644                         (pDlContext->tRWInfo.bFramesSegmented) = TRUE;
    645                     }
    646                 }
    647             }
    648         }
    649         else if(phDnldNfc_FTLog == (pDlContext->FrameInp.Type))
    650         {
    651             if((0 == (pDlContext->tUserData.wLen)) || (NULL == (pDlContext->tUserData.pBuff)))
    652             {
    653                 NXPLOG_FWDNLD_E("Invalid Input Parameter(s) for Log!!");
    654                 wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
    655             }
    656         }
    657         else
    658         {
    659         }
    660 
    661         if(NFCSTATUS_SUCCESS == wStatus)
    662         {
    663             wStatus = phDnldNfc_CreateFramePld(pDlContext);
    664         }
    665 
    666         if(NFCSTATUS_SUCCESS == wStatus)
    667         {
    668             wFrameLen = 0;
    669             wFrameLen  = (pDlContext->tCmdRspFrameInfo.dwSendlength);
    670 
    671             if(phDnldNfc_FTRaw != (pDlContext->FrameInp.Type))
    672             {
    673                 if(phDnldNfc_FTWrite != (pDlContext->FrameInp.Type))
    674                 {
    675                     pFrameByte = (uint8_t *)&wFrameLen;
    676 
    677                     pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_HDR_OFFSET] = pFrameByte[1];
    678                     pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_HDR_OFFSET + 1] = pFrameByte[0];
    679 
    680                     NXPLOG_FWDNLD_D("Inserting FrameId ..");
    681                     pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAMEID_OFFSET] =
    682                         (pDlContext->tCmdId);
    683 
    684                     wFrameLen += PHDNLDNFC_FRAME_HDR_LEN;
    685                 }
    686                 else
    687                 {
    688                     if(0 != (pDlContext->tRWInfo.wRWPldSize))
    689                     {
    690                         if(TRUE == (pDlContext->tRWInfo.bFramesSegmented))
    691                         {
    692                             /* Turning ON the Fragmentation bit in FrameLen */
    693                             wFrameLen = PHDNLDNFC_SET_HDR_FRAGBIT(wFrameLen);
    694                         }
    695 
    696                         pFrameByte = (uint8_t *)&wFrameLen;
    697 
    698                         pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_HDR_OFFSET] = pFrameByte[1];
    699                         pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_HDR_OFFSET + 1] = pFrameByte[0];
    700 
    701                         /* To ensure we have no frag bit set for crc calculation */
    702                         wFrameLen = PHDNLDNFC_CLR_HDR_FRAGBIT(wFrameLen);
    703 
    704                         wFrameLen += PHDNLDNFC_FRAME_HDR_LEN;
    705                     }
    706                 }
    707                 if (wFrameLen > PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE)
    708                 {
    709                     NXPLOG_FWDNLD_D ("wFrameLen exceeds the limit");
    710                     return NFCSTATUS_FAILED;
    711                 }
    712                 /* calculate CRC16 */
    713                 wCrcVal = phDnldNfc_CalcCrc16((pDlContext->tCmdRspFrameInfo.aFrameBuff),wFrameLen);
    714 
    715                 pFrameByte = (uint8_t *)&wCrcVal;
    716 
    717                 /* Insert the computed Crc value */
    718                 pDlContext->tCmdRspFrameInfo.aFrameBuff[wFrameLen] = pFrameByte[1];
    719                 pDlContext->tCmdRspFrameInfo.aFrameBuff[wFrameLen+ 1] = pFrameByte[0];
    720 
    721                 wFrameLen += PHDNLDNFC_FRAME_CRC_LEN;
    722             }
    723 
    724             (pDlContext->tCmdRspFrameInfo.dwSendlength) = wFrameLen;
    725             NXPLOG_FWDNLD_D("Frame created successfully");
    726         }
    727         else
    728         {
    729             NXPLOG_FWDNLD_E("Frame creation failed!!");
    730             wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
    731         }
    732     }
    733 
    734     return wStatus;
    735 }
    736 
    737 /*******************************************************************************
    738 **
    739 ** Function         phDnldNfc_CreateFramePld
    740 **
    741 ** Description      Forms the frame payload
    742 **
    743 ** Parameters       pDlContext - pointer to the download context structure
    744 **
    745 ** Returns          NFC status
    746 **
    747 *******************************************************************************/
    748 static NFCSTATUS phDnldNfc_CreateFramePld(pphDnldNfc_DlContext_t pDlContext)
    749 {
    750     NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    751     uint16_t wBuffIdx = 0;
    752     uint16_t wChkIntgVal = 0;
    753     uint16_t wFrameLen = 0;
    754 
    755     if(NULL == pDlContext)
    756     {
    757         NXPLOG_FWDNLD_E("Invalid Input Parameter!!");
    758         wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
    759     }
    760     else
    761     {
    762         memset((pDlContext->tCmdRspFrameInfo.aFrameBuff),0,PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE);
    763         (pDlContext->tCmdRspFrameInfo.dwSendlength) = 0;
    764 
    765         if(phDnldNfc_FTNone == (pDlContext->FrameInp.Type))
    766         {
    767             (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_MIN_PLD_LEN;
    768         }
    769         else if(phDnldNfc_ChkIntg == (pDlContext->FrameInp.Type))
    770         {
    771             (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_MIN_PLD_LEN;
    772 
    773             wChkIntgVal = PHDNLDNFC_USERDATA_EEPROM_OFFSET;
    774             memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_RDDATA_OFFSET]),
    775                         &wChkIntgVal,sizeof(wChkIntgVal));
    776 
    777             wChkIntgVal = PHDNLDNFC_USERDATA_EEPROM_LEN;
    778             memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_RDDATA_OFFSET +
    779                 PHDNLDNFC_USERDATA_EEPROM_OFFSIZE]),&wChkIntgVal,sizeof(wChkIntgVal));
    780 
    781             (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_USERDATA_EEPROM_LENSIZE;
    782             (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_USERDATA_EEPROM_OFFSIZE;
    783         }
    784         else if(phDnldNfc_FTWrite == (pDlContext->FrameInp.Type))
    785         {
    786             wBuffIdx = (pDlContext->tRWInfo.wOffset);
    787 
    788             if(FALSE == (pDlContext->tRWInfo.bFramesSegmented))
    789             {
    790                 wFrameLen = (pDlContext->tUserData.pBuff[wBuffIdx]);
    791                 wFrameLen <<= 8;
    792                 wFrameLen |= (pDlContext->tUserData.pBuff[wBuffIdx + 1]);
    793 
    794                 (pDlContext->tRWInfo.wRWPldSize) = wFrameLen;
    795             }
    796 
    797             if((pDlContext->tRWInfo.wRWPldSize) > PHDNLDNFC_CMDRESP_MAX_PLD_SIZE)
    798             {
    799                 if(FALSE == (pDlContext->tRWInfo.bFirstChunkResp))
    800                 {
    801                     (pDlContext->tRWInfo.wRemChunkBytes) = wFrameLen;
    802                     (pDlContext->tRWInfo.wOffset) += PHDNLDNFC_FRAME_HDR_LEN;
    803                     wBuffIdx = (pDlContext->tRWInfo.wOffset);
    804                 }
    805 
    806                 if(PHDNLDNFC_CMDRESP_MAX_PLD_SIZE < (pDlContext->tRWInfo.wRemChunkBytes))
    807                 {
    808                     (pDlContext->tRWInfo.wBytesToSendRecv) = PHDNLDNFC_CMDRESP_MAX_PLD_SIZE;
    809                     (pDlContext->tRWInfo.bFramesSegmented) = TRUE;
    810                 }
    811                 else
    812                 {
    813                     (pDlContext->tRWInfo.wBytesToSendRecv) = (pDlContext->tRWInfo.wRemChunkBytes);
    814                     (pDlContext->tRWInfo.bFramesSegmented) = FALSE;
    815                 }
    816 
    817                 memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAMEID_OFFSET]),
    818                         &(pDlContext->tUserData.pBuff[wBuffIdx]),(pDlContext->tRWInfo.wBytesToSendRecv));
    819             }
    820             else
    821             {
    822                 (pDlContext->tRWInfo.wRWPldSize) = 0;
    823                 (pDlContext->tRWInfo.wBytesToSendRecv) = (wFrameLen + PHDNLDNFC_FRAME_HDR_LEN);
    824 
    825                 memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[0]),
    826                     &(pDlContext->tUserData.pBuff[wBuffIdx]),(pDlContext->tRWInfo.wBytesToSendRecv));
    827             }
    828             (pDlContext->tCmdRspFrameInfo.dwSendlength) += (pDlContext->tRWInfo.wBytesToSendRecv);
    829         }
    830         else if(phDnldNfc_FTRead == (pDlContext->FrameInp.Type))
    831         {
    832             (pDlContext->tRWInfo.wBytesToSendRecv) = ((pDlContext->tRWInfo.wRemBytes) >
    833                     (pDlContext->tRWInfo.wRWPldSize)) ? (pDlContext->tRWInfo.wRWPldSize) :
    834                     (pDlContext->tRWInfo.wRemBytes);
    835 
    836             wBuffIdx = (PHDNLDNFC_PLD_OFFSET + ((sizeof(pDlContext->tRWInfo.wBytesToSendRecv))
    837                         % PHDNLDNFC_MIN_PLD_LEN) - 1);
    838 
    839             memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]),
    840                 &(pDlContext->tRWInfo.wBytesToSendRecv),(sizeof(pDlContext->tRWInfo.wBytesToSendRecv)));
    841 
    842             wBuffIdx += sizeof(pDlContext->tRWInfo.wBytesToSendRecv);
    843 
    844             memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]),
    845                 &(pDlContext->tRWInfo.dwAddr),sizeof(pDlContext->tRWInfo.dwAddr));
    846 
    847             (pDlContext->tCmdRspFrameInfo.dwSendlength) += (PHDNLDNFC_MIN_PLD_LEN +
    848                 (sizeof(pDlContext->tRWInfo.dwAddr)));
    849         }
    850         else if(phDnldNfc_FTLog == (pDlContext->FrameInp.Type))
    851         {
    852             (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_MIN_PLD_LEN;
    853 
    854             wBuffIdx = (PHDNLDNFC_MIN_PLD_LEN + PHDNLDNFC_FRAME_HDR_LEN);
    855 
    856             memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]),
    857                 (pDlContext->tUserData.pBuff),(pDlContext->tUserData.wLen));
    858 
    859             (pDlContext->tCmdRspFrameInfo.dwSendlength) += (pDlContext->tUserData.wLen);
    860         }
    861         else if(phDnldNfc_FTForce == (pDlContext->FrameInp.Type))
    862         {
    863             (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_MIN_PLD_LEN;
    864 
    865             wBuffIdx = PHDNLDNFC_PLD_OFFSET;
    866 
    867             memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]),
    868                 (pDlContext->tUserData.pBuff),(pDlContext->tUserData.wLen));
    869         }
    870         else if(phDnldNfc_FTRaw == (pDlContext->FrameInp.Type))
    871         {
    872             if((0 == (pDlContext->tUserData.wLen)) || (NULL == (pDlContext->tUserData.pBuff)))
    873             {
    874                 NXPLOG_FWDNLD_E("Invalid Input Parameter(s) for Raw Request!!");
    875                 wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
    876             }
    877             else
    878             {
    879                 memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]),
    880                     (pDlContext->tUserData.pBuff),(pDlContext->tUserData.wLen));
    881 
    882                 (pDlContext->tCmdRspFrameInfo.dwSendlength) += (pDlContext->tUserData.wLen);
    883             }
    884         }
    885         else
    886         {
    887         }
    888     }
    889 
    890     return wStatus;
    891 }
    892 
    893 /*******************************************************************************
    894 **
    895 ** Function         phDnldNfc_ProcessFrame
    896 **
    897 ** Description      Processes response frame received
    898 **
    899 ** Parameters       pContext - pointer to the download context structure
    900 **                  pInfo    - pointer to the Transaction buffer updated by TML Thread
    901 **
    902 ** Returns          NFCSTATUS_SUCCESS               - parameters successfully validated
    903 **                  NFCSTATUS_INVALID_PARAMETER     - invalid parameters
    904 **
    905 *******************************************************************************/
    906 static NFCSTATUS phDnldNfc_ProcessFrame(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
    907 {
    908     NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    909     uint16_t wCrcVal,wRecvdCrc,wRecvdLen,wPldLen;
    910     pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
    911 
    912     if((NULL == pDlCtxt) ||
    913        (NULL == pInfo)
    914        )
    915     {
    916         NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
    917         wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
    918     }
    919     else
    920     {
    921         if((PH_DL_STATUS_OK != pInfo->wStatus) ||
    922             (0 == pInfo->wLength) ||
    923             (NULL == pInfo->pBuff))
    924         {
    925             NXPLOG_FWDNLD_E("Dnld Cmd Request Failed!!");
    926             wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
    927         }
    928         else
    929         {
    930             if(phDnldNfc_FTRaw == (pDlCtxt->FrameInp.Type))
    931             {
    932               if((0 != (pDlCtxt->tRspBuffInfo.wLen)) &&
    933                     (NULL != (pDlCtxt->tRspBuffInfo.pBuff)))
    934               {
    935                   memcpy((pDlCtxt->tRspBuffInfo.pBuff),(pInfo->pBuff),(pInfo->wLength));
    936 
    937                   (pDlCtxt->tRspBuffInfo.wLen) = (pInfo->wLength);
    938               }
    939               else
    940               {
    941                   NXPLOG_FWDNLD_E("Cannot update Response buff with received data!!");
    942               }
    943             }
    944             else
    945             {
    946                 /* calculate CRC16 */
    947                 wCrcVal = phDnldNfc_CalcCrc16((pInfo->pBuff),((pInfo->wLength) - PHDNLDNFC_FRAME_CRC_LEN));
    948 
    949                 wRecvdCrc = 0;
    950                 wRecvdCrc = (((uint16_t)(pInfo->pBuff[(pInfo->wLength) - 2]) << 8U) |
    951                                (pInfo->pBuff[(pInfo->wLength) - 1]));
    952 
    953                 if(wRecvdCrc == wCrcVal)
    954                 {
    955                     wRecvdLen = (((uint16_t)(pInfo->pBuff[PHDNLDNFC_FRAME_HDR_OFFSET]) << 8U) |
    956                                (pInfo->pBuff[PHDNLDNFC_FRAME_HDR_OFFSET + 1]));
    957 
    958                     wPldLen = ((pInfo->wLength) - (PHDNLDNFC_FRAME_HDR_LEN + PHDNLDNFC_FRAME_CRC_LEN));
    959 
    960                     if(wRecvdLen != wPldLen)
    961                     {
    962                         NXPLOG_FWDNLD_E("Invalid frame payload length received");
    963                         wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
    964                     }
    965                     else
    966                     {
    967                         wStatus = phDnldNfc_UpdateRsp(pDlCtxt,pInfo,(wPldLen - 1));
    968                     }
    969                 }
    970                 else
    971                 {
    972                     NXPLOG_FWDNLD_E("Invalid frame received");
    973                     wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
    974                 }
    975             }
    976         }
    977     }
    978 
    979     return wStatus;
    980 }
    981 
    982 /*******************************************************************************
    983 **
    984 ** Function         phDnldNfc_ProcessRecvInfo
    985 **
    986 ** Description      Processes the response during the state phDnldNfc_StateRecv
    987 **
    988 ** Parameters       pContext - pointer to the download context structure
    989 **                  pInfo    - pointer to the Transaction buffer updated by TML Thread
    990 **
    991 ** Returns          NFCSTATUS_SUCCESS               - parameters successfully validated
    992 **                  NFCSTATUS_INVALID_PARAMETER     - invalid parameters
    993 **
    994 *******************************************************************************/
    995 static NFCSTATUS phDnldNfc_ProcessRecvInfo(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
    996 {
    997     NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    998 
    999     if(NULL != pContext)
   1000     {
   1001         if (NULL == pInfo)
   1002         {
   1003             NXPLOG_FWDNLD_E("Invalid pInfo received from TML!!");
   1004             wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
   1005         }
   1006         else
   1007         {
   1008             wStatus = PHNFCSTATUS(pInfo->wStatus);
   1009 
   1010             if(NFCSTATUS_SUCCESS == wStatus)
   1011             {
   1012                 NXPLOG_FWDNLD_D("Send Success");
   1013             }else
   1014             {
   1015                 NXPLOG_FWDNLD_E("Tml Write error!!");
   1016                  wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
   1017             }
   1018         }
   1019     }
   1020     else
   1021     {
   1022         NXPLOG_FWDNLD_E("Invalid context received from TML!!");
   1023          wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
   1024     }
   1025 
   1026     return wStatus;
   1027 }
   1028 
   1029 /*******************************************************************************
   1030 **
   1031 ** Function         phDnldNfc_SetupResendTimer
   1032 **
   1033 ** Description      Sets up the timer for resending the previous write frame
   1034 **
   1035 ** Parameters       pDlContext - pointer to the download context structure
   1036 **
   1037 ** Returns          NFC status
   1038 **
   1039 *******************************************************************************/
   1040 static NFCSTATUS phDnldNfc_SetupResendTimer(pphDnldNfc_DlContext_t pDlContext)
   1041 {
   1042     NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1043 
   1044     wStatus = phOsalNfc_Timer_Start((pDlContext->TimerInfo.dwRspTimerId),
   1045                                                 PHDNLDNFC_RETRY_FRAME_WRITE,
   1046                                                 &phDnldNfc_ResendTimeOutCb,
   1047                                                 pDlContext);
   1048 
   1049     if(NFCSTATUS_SUCCESS == wStatus)
   1050     {
   1051         NXPLOG_FWDNLD_D("Frame Resend wait timer started");
   1052         (pDlContext->TimerInfo.TimerStatus) = 1;
   1053         pDlContext->tCurrState = phDnldNfc_StateTimer;
   1054     }
   1055     else
   1056     {
   1057          NXPLOG_FWDNLD_W("Frame Resend wait timer not started");
   1058          (pDlContext->TimerInfo.TimerStatus) = 0;/*timer stopped*/
   1059          pDlContext->tCurrState = phDnldNfc_StateResponse;
   1060         /* Todo:- diagnostic in this case */
   1061     }
   1062 
   1063     return wStatus;
   1064 }
   1065 
   1066 #if !defined(PH_LIBNFC_VEN_RESET_ON_DOWNLOAD_TIMEOUT)
   1067 #   error PH_LIBNFC_VEN_RESET_ON_DOWNLOAD_TIMEOUT has to be defined
   1068 #endif
   1069 
   1070 /*******************************************************************************
   1071 **
   1072 ** Function         phDnldNfc_RspTimeOutCb
   1073 **
   1074 ** Description      Callback function in case of timer expiration
   1075 **
   1076 ** Parameters       TimerId  - expired timer id
   1077 **                  pContext - pointer to the download context structure
   1078 **
   1079 ** Returns          None
   1080 **
   1081 *******************************************************************************/
   1082 static void phDnldNfc_RspTimeOutCb(uint32_t TimerId, void *pContext)
   1083 {
   1084     pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
   1085 
   1086     if (NULL != pDlCtxt)
   1087     {
   1088         UNUSED(TimerId);
   1089 
   1090         if(1 == pDlCtxt->TimerInfo.TimerStatus)
   1091         {
   1092             /* No response received and the timer expired */
   1093             pDlCtxt->TimerInfo.TimerStatus = 0;    /* Reset timer status flag */
   1094 
   1095             NXPLOG_FWDNLD_D("%x",pDlCtxt->tLastStatus);
   1096 
   1097 #if PH_LIBNFC_VEN_RESET_ON_DOWNLOAD_TIMEOUT
   1098             if ( PH_DL_STATUS_SIGNATURE_ERROR  == pDlCtxt->tLastStatus ) {
   1099                 /* Do a VEN Reset of the chip. */
   1100                 NXPLOG_FWDNLD_E("Performing a VEN Reset");
   1101                 phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
   1102                 phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
   1103                 NXPLOG_FWDNLD_E("VEN Reset Done");
   1104             }
   1105 #endif
   1106 
   1107 
   1108             (pDlCtxt->TimerInfo.wTimerExpStatus) = NFCSTATUS_RF_TIMEOUT;
   1109 
   1110             if((phDnldNfc_EventRead == pDlCtxt->tCurrEvent) || (phDnldNfc_EventWrite == pDlCtxt->tCurrEvent))
   1111             {
   1112                 phDnldNfc_ProcessRWSeqState(pDlCtxt,NULL);
   1113             }
   1114             else
   1115             {
   1116                 phDnldNfc_ProcessSeqState(pDlCtxt,NULL);
   1117             }
   1118         }
   1119     }
   1120 
   1121     return;
   1122 }
   1123 
   1124 /*******************************************************************************
   1125 **
   1126 ** Function         phDnldNfc_ResendTimeOutCb
   1127 **
   1128 ** Description      Callback function in case of Frame Resend Wait timer expiration
   1129 **
   1130 ** Parameters       TimerId  - expired timer id
   1131 **                  pContext - pointer to the download context structure
   1132 **
   1133 ** Returns          None
   1134 **
   1135 *******************************************************************************/
   1136 static void phDnldNfc_ResendTimeOutCb(uint32_t TimerId, void *pContext)
   1137 {
   1138     pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
   1139 
   1140     if (NULL != pDlCtxt)
   1141     {
   1142         UNUSED(TimerId);
   1143 
   1144         if(1 == pDlCtxt->TimerInfo.TimerStatus)
   1145         {
   1146             /* No response received and the timer expired */
   1147             pDlCtxt->TimerInfo.TimerStatus = 0;    /* Reset timer status flag */
   1148 
   1149             (pDlCtxt->TimerInfo.wTimerExpStatus) = 0;
   1150 
   1151              pDlCtxt->tCurrState = phDnldNfc_StateSend;
   1152 
   1153              /* set the flag to trigger last frame re-transmission */
   1154              pDlCtxt->bResendLastFrame = TRUE;
   1155 
   1156              phDnldNfc_ProcessRWSeqState(pDlCtxt,NULL);
   1157         }
   1158     }
   1159 
   1160     return;
   1161 }
   1162 
   1163 /*******************************************************************************
   1164 **
   1165 ** Function         phDnldNfc_UpdateRsp
   1166 **
   1167 ** Description      verifies the payload status byte and copies data
   1168 **                  to response buffer if successful
   1169 **
   1170 ** Parameters       pDlContext - pointer to the download context structure
   1171 **                  pInfo      - pointer to the Transaction buffer updated by TML Thread
   1172 **                  wPldLen    - Length of the payload bytes to copy to response buffer
   1173 **
   1174 ** Returns          NFC status
   1175 **
   1176 *******************************************************************************/
   1177 static NFCSTATUS phDnldNfc_UpdateRsp(pphDnldNfc_DlContext_t   pDlContext, phTmlNfc_TransactInfo_t  *pInfo, uint16_t wPldLen)
   1178 {
   1179     NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1180     uint16_t wReadLen = 0;
   1181 
   1182     if((NULL == pDlContext) || (NULL == pInfo))
   1183     {
   1184         NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
   1185         wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
   1186     }
   1187     else
   1188     {
   1189         if(PH_DL_CMD_WRITE == (pDlContext->tCmdId))
   1190         {
   1191             if(PH_DL_STATUS_OK == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
   1192             {
   1193                 /* first write frame response received case */
   1194                 if(TRUE == (pDlContext->tRWInfo.bFirstWrReq))
   1195                 {
   1196                     NXPLOG_FWDNLD_D("First Write Frame Success Status received!!");
   1197                     (pDlContext->tRWInfo.bFirstWrReq) = FALSE;
   1198                 }
   1199 
   1200                 if(TRUE == (pDlContext->tRWInfo.bFirstChunkResp))
   1201                 {
   1202                     if(FALSE == (pDlContext->tRWInfo.bFramesSegmented))
   1203                     {
   1204                         NXPLOG_FWDNLD_D("Chunked Write Frame Success Status received!!");
   1205                         (pDlContext->tRWInfo.wRemChunkBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
   1206                         (pDlContext->tRWInfo.bFirstChunkResp) = FALSE;
   1207                     }
   1208                     else
   1209                     {
   1210                         NXPLOG_FWDNLD_E("UnExpected Status received!!");
   1211                         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED);
   1212                     }
   1213                 }
   1214 
   1215                 if(NFCSTATUS_SUCCESS == wStatus)
   1216                 {
   1217                     (pDlContext->tRWInfo.wRemBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
   1218                     (pDlContext->tRWInfo.wOffset) += (pDlContext->tRWInfo.wBytesToSendRecv);
   1219                 }
   1220             }
   1221             else if((FALSE == (pDlContext->tRWInfo.bFirstChunkResp)) &&
   1222                 (TRUE == (pDlContext->tRWInfo.bFramesSegmented)) &&
   1223                 (PHDNLDNFC_FIRST_FRAGFRAME_RESP == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET])))
   1224             {
   1225                 (pDlContext->tRWInfo.bFirstChunkResp) = TRUE;
   1226                 (pDlContext->tRWInfo.wRemChunkBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
   1227                 (pDlContext->tRWInfo.wRemBytes) -= ((pDlContext->tRWInfo.wBytesToSendRecv) + PHDNLDNFC_FRAME_HDR_LEN);
   1228                 (pDlContext->tRWInfo.wOffset) += (pDlContext->tRWInfo.wBytesToSendRecv);
   1229 
   1230                 /* first write frame response received case */
   1231                 if(TRUE == (pDlContext->tRWInfo.bFirstWrReq))
   1232                 {
   1233                     NXPLOG_FWDNLD_D("First Write Frame Success Status received!!");
   1234                     (pDlContext->tRWInfo.bFirstWrReq) = FALSE;
   1235                 }
   1236             }
   1237             else if((TRUE == (pDlContext->tRWInfo.bFirstChunkResp)) &&
   1238                 (TRUE == (pDlContext->tRWInfo.bFramesSegmented)) &&
   1239                 (PHDNLDNFC_NEXT_FRAGFRAME_RESP == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET])))
   1240             {
   1241                 (pDlContext->tRWInfo.wRemChunkBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
   1242                 (pDlContext->tRWInfo.wRemBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
   1243                 (pDlContext->tRWInfo.wOffset) += (pDlContext->tRWInfo.wBytesToSendRecv);
   1244             }
   1245             else if(PH_DL_STATUS_FIRMWARE_VERSION_ERROR == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
   1246             {
   1247                 NXPLOG_FWDNLD_E("FW version Error !!!could be either due to FW major version mismatch or Firmware Already Up To Date !!");
   1248                 (pDlContext->tRWInfo.bFirstWrReq) = FALSE;
   1249                 /* resetting wRemBytes to 0 to avoid any further write frames send */
   1250                 (pDlContext->tRWInfo.wRemBytes) = 0;
   1251                 (pDlContext->tRWInfo.wOffset) = 0;
   1252                 wStatus = NFCSTATUS_FW_VERSION_ERROR;
   1253             }
   1254             else if(PH_DL_STATUS_PLL_ERROR == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
   1255             {
   1256                 NXPLOG_FWDNLD_E("PLL Error Status received!!");
   1257                 (pDlContext->tLastStatus) = PH_DL_STATUS_PLL_ERROR;
   1258                 wStatus = NFCSTATUS_WRITE_FAILED;
   1259             }
   1260             else if(PH_DL_STATUS_SIGNATURE_ERROR == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
   1261             {
   1262                 NXPLOG_FWDNLD_E("Signature Mismatch Error received!!");
   1263                 /* save the status for use in loading the relevant recovery image (either signature or platform) */
   1264                 (pDlContext->tLastStatus) = PH_DL_STATUS_SIGNATURE_ERROR;
   1265                 wStatus = NFCSTATUS_REJECTED;
   1266             }
   1267             else if(PH_DL_STATUS_MEM_BSY == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
   1268             {
   1269                 NXPLOG_FWDNLD_E("Mem Busy Status received!!");
   1270                 (pDlContext->tLastStatus) = PH_DL_STATUS_MEM_BSY;
   1271                 wStatus = NFCSTATUS_BUSY;
   1272             }
   1273             else
   1274             {
   1275                 NXPLOG_FWDNLD_E("Unsuccessful Status received!!");
   1276                 wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED);
   1277             }
   1278         }
   1279         else if(PH_DL_CMD_READ == (pDlContext->tCmdId))
   1280         {
   1281             if(PH_DL_STATUS_OK == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
   1282             {
   1283                 wReadLen = (((uint16_t)(pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET + 3]) << 8U) |
   1284                            (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET + 2]));
   1285 
   1286                 if(wReadLen != (pDlContext->tRWInfo.wBytesToSendRecv))
   1287                 {
   1288                     NXPLOG_FWDNLD_E("Desired Length bytes not received!!");
   1289                     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED);
   1290                 }
   1291                 else
   1292                 {
   1293                     memcpy(&(pDlContext->tRspBuffInfo.pBuff[(pDlContext->tRWInfo.wOffset)]),
   1294                         &(pInfo->pBuff[PHDNLDNFC_FRAME_RDDATA_OFFSET]),
   1295                         wReadLen);
   1296 
   1297                     (pDlContext->tRWInfo.wBytesRead) += wReadLen;
   1298 
   1299                     (pDlContext->tRspBuffInfo.wLen) = (pDlContext->tRWInfo.wBytesRead);
   1300 
   1301                     (pDlContext->tRWInfo.wRemBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
   1302                     (pDlContext->tRWInfo.dwAddr) += (pDlContext->tRWInfo.wBytesToSendRecv);
   1303                     (pDlContext->tRWInfo.wOffset) += (pDlContext->tRWInfo.wBytesToSendRecv);
   1304                 }
   1305             }
   1306             else
   1307             {
   1308                 NXPLOG_FWDNLD_E("Unsuccessful Status received!!");
   1309                 wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED);
   1310             }
   1311         }
   1312         else
   1313         {
   1314             if(PH_DL_STATUS_OK == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
   1315             {
   1316                 if((0 != (pDlContext->tRspBuffInfo.wLen)) &&
   1317                     (NULL != (pDlContext->tRspBuffInfo.pBuff)))
   1318                 {
   1319                     memcpy((pDlContext->tRspBuffInfo.pBuff),&(pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET + 1]),
   1320                         wPldLen);
   1321 
   1322                     (pDlContext->tRspBuffInfo.wLen) = wPldLen;
   1323                 }
   1324             }
   1325             else
   1326             {
   1327                 NXPLOG_FWDNLD_E("Unsuccessful Status received!!");
   1328                 wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED);
   1329             }
   1330         }
   1331     }
   1332 
   1333     return wStatus;
   1334 }
   1335