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