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