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