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