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 */ 78static void phDnldNfc_ProcessSeqState(void *pContext, phTmlNfc_TransactInfo_t *pInfo); 79static void phDnldNfc_ProcessRWSeqState(void *pContext, phTmlNfc_TransactInfo_t *pInfo); 80static NFCSTATUS phDnldNfc_ProcessFrame(void *pContext, phTmlNfc_TransactInfo_t *pInfo); 81static NFCSTATUS phDnldNfc_ProcessRecvInfo(void *pContext, phTmlNfc_TransactInfo_t *pInfo); 82static NFCSTATUS phDnldNfc_BuildFramePkt(pphDnldNfc_DlContext_t pDlContext); 83static NFCSTATUS phDnldNfc_CreateFramePld(pphDnldNfc_DlContext_t pDlContext); 84static NFCSTATUS phDnldNfc_SetupResendTimer(pphDnldNfc_DlContext_t pDlContext); 85static NFCSTATUS phDnldNfc_UpdateRsp(pphDnldNfc_DlContext_t pDlContext, phTmlNfc_TransactInfo_t *pInfo, uint16_t wPldLen); 86static void phDnldNfc_RspTimeOutCb(uint32_t TimerId, void *pContext); 87static 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*******************************************************************************/ 112NFCSTATUS 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*******************************************************************************/ 196static 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*******************************************************************************/ 372static 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*******************************************************************************/ 592static 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*******************************************************************************/ 748static 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*******************************************************************************/ 906static 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*******************************************************************************/ 995static 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*******************************************************************************/ 1040static 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*******************************************************************************/ 1082static 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*******************************************************************************/ 1136static 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*******************************************************************************/ 1177static 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