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