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