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  * Download Component
19  * Download Interface routines implementation
20  */
21 
22 #include <dlfcn.h>
23 #include <phDnldNfc_Internal.h>
24 #include <phNxpConfig.h>
25 #include <phNxpLog.h>
26 #include <phTmlNfc.h>
27 #include <string>
28 static void* pFwHandle; /* Global firmware handle */
29 uint16_t wMwVer = 0;    /* Middleware version no */
30 uint16_t wFwVer = 0;    /* Firmware version no */
31 uint8_t gRecFWDwnld;    // flag set to true to indicate dummy FW download
32 phTmlNfc_i2cfragmentation_t fragmentation_enabled = I2C_FRAGMENATATION_DISABLED;
33 static pphDnldNfc_DlContext_t gpphDnldContext = NULL; /* Download contex */
34 #undef EEPROM_Read_Mem_IMP
35 
36 /*******************************************************************************
37 **
38 ** Function         phDnldNfc_Reset
39 **
40 ** Description      Performs a soft reset of the download module
41 **
42 ** Parameters       pNotify  - notify caller after getting response
43 **                  pContext - caller context
44 **
45 ** Returns          NFC status:
46 **                  NFCSTATUS_SUCCESS - reset request to NFCC is successful
47 **                  NFCSTATUS_FAILED - reset request failed due to internal
48 **                                     error
49 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
50 **                  Other command specific errors
51 **
52 *******************************************************************************/
phDnldNfc_Reset(pphDnldNfc_RspCb_t pNotify,void * pContext)53 NFCSTATUS phDnldNfc_Reset(pphDnldNfc_RspCb_t pNotify, void* pContext) {
54   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
55 
56   if ((NULL == pNotify) || (NULL == pContext)) {
57     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
58     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
59   } else {
60     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
61       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
62       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
63     } else {
64       (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
65       (gpphDnldContext->tCmdId) = PH_DL_CMD_RESET;
66       (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
67       (gpphDnldContext->tRspBuffInfo.wLen) = 0;
68       (gpphDnldContext->tUserData.pBuff) = NULL;
69       (gpphDnldContext->tUserData.wLen) = 0;
70       (gpphDnldContext->UserCb) = pNotify;
71       (gpphDnldContext->UserCtxt) = pContext;
72 
73       wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventReset);
74 
75       if (NFCSTATUS_PENDING == wStatus) {
76         NXPLOG_FWDNLD_D("Reset Request submitted successfully");
77       } else {
78         NXPLOG_FWDNLD_E("Reset Request Failed!!");
79       }
80     }
81   }
82 
83   return wStatus;
84 }
85 
86 /*******************************************************************************
87 **
88 ** Function         phDnldNfc_GetVersion
89 **
90 ** Description      Retrieves Hardware version, ROM Code version, Protected Data
91 **                  version, Trim data version, User data version, and Firmware
92 **                  version information
93 **
94 ** Parameters       pVersionInfo - response buffer which gets updated with
95 **                                 complete version info from NFCC
96 **                  pNotify - notify caller after getting response
97 **                  pContext - caller context
98 **
99 ** Returns          NFC status:
100 **                  NFCSTATUS_SUCCESS - GetVersion request to NFCC is successful
101 **                  NFCSTATUS_FAILED - GetVersion request failed due to internal
102 **                                     error
103 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
104 **                  Other command specific errors
105 **
106 *******************************************************************************/
phDnldNfc_GetVersion(pphDnldNfc_Buff_t pVersionInfo,pphDnldNfc_RspCb_t pNotify,void * pContext)107 NFCSTATUS phDnldNfc_GetVersion(pphDnldNfc_Buff_t pVersionInfo,
108                                pphDnldNfc_RspCb_t pNotify, void* pContext) {
109   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
110 
111   if ((NULL == pVersionInfo) || (NULL == pNotify) || (NULL == pContext)) {
112     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
113     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
114   } else {
115     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
116       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
117       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
118     } else {
119       if ((NULL != pVersionInfo->pBuff) && (0 != pVersionInfo->wLen)) {
120         (gpphDnldContext->tRspBuffInfo.pBuff) = pVersionInfo->pBuff;
121         (gpphDnldContext->tRspBuffInfo.wLen) = pVersionInfo->wLen;
122         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
123         (gpphDnldContext->tCmdId) = PH_DL_CMD_GETVERSION;
124         (gpphDnldContext->tUserData.pBuff) = NULL;
125         (gpphDnldContext->tUserData.wLen) = 0;
126         (gpphDnldContext->UserCb) = pNotify;
127         (gpphDnldContext->UserCtxt) = pContext;
128 
129         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventGetVer);
130 
131         if (NFCSTATUS_PENDING == wStatus) {
132           NXPLOG_FWDNLD_D("GetVersion Request submitted successfully");
133         } else {
134           NXPLOG_FWDNLD_E("GetVersion Request Failed!!");
135         }
136       } else {
137         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
138         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
139       }
140     }
141   }
142 
143   return wStatus;
144 }
145 
146 /*******************************************************************************
147 **
148 ** Function         phDnldNfc_GetSessionState
149 **
150 ** Description      Retrieves the current session state of NFCC
151 **
152 ** Parameters       pSession - response buffer which gets updated with complete
153 **                             version info from NFCC
154 **                  pNotify - notify caller after getting response
155 **                  pContext - caller context
156 **
157 ** Returns          NFC status:
158 **                  NFCSTATUS_SUCCESS - GetSessionState request to NFCC is
159 **                                      successful
160 **                  NFCSTATUS_FAILED - GetSessionState request failed due to
161 **                                     internal error
162 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
163 **                  Other command specific errors
164 **
165 *******************************************************************************/
phDnldNfc_GetSessionState(pphDnldNfc_Buff_t pSession,pphDnldNfc_RspCb_t pNotify,void * pContext)166 NFCSTATUS phDnldNfc_GetSessionState(pphDnldNfc_Buff_t pSession,
167                                     pphDnldNfc_RspCb_t pNotify,
168                                     void* pContext) {
169   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
170 
171   if ((NULL == pSession) || (NULL == pNotify) || (NULL == pContext)) {
172     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
173     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
174   } else {
175     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
176       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
177       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
178     } else {
179       if ((NULL != pSession->pBuff) && (0 != pSession->wLen)) {
180         (gpphDnldContext->tRspBuffInfo.pBuff) = pSession->pBuff;
181         (gpphDnldContext->tRspBuffInfo.wLen) = pSession->wLen;
182         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
183         (gpphDnldContext->tCmdId) = PH_DL_CMD_GETSESSIONSTATE;
184         (gpphDnldContext->tUserData.pBuff) = NULL;
185         (gpphDnldContext->tUserData.wLen) = 0;
186         (gpphDnldContext->UserCb) = pNotify;
187         (gpphDnldContext->UserCtxt) = pContext;
188 
189         wStatus =
190             phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventGetSesnSt);
191 
192         if (NFCSTATUS_PENDING == wStatus) {
193           NXPLOG_FWDNLD_D("GetSessionState Request submitted successfully");
194         } else {
195           NXPLOG_FWDNLD_E("GetSessionState Request Failed!!");
196         }
197       } else {
198         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
199         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
200       }
201     }
202   }
203 
204   return wStatus;
205 }
206 
207 /*******************************************************************************
208 **
209 ** Function         phDnldNfc_CheckIntegrity
210 **
211 ** Description      Inspects the integrity of EEPROM and FLASH contents of the
212 **                  NFCC, provides CRC for each section
213 **                  NOTE: The user data section CRC is valid only after fresh
214 **                        download
215 **
216 ** Parameters       bChipVer - current ChipVersion for including additional
217 **                             parameters in request payload
218 **                  pCRCData - response buffer which gets updated with
219 **                             respective section CRC status and CRC bytes from
220 **                             NFCC
221 **                  pNotify - notify caller after getting response
222 **                  pContext - caller context
223 **
224 ** Returns          NFC status:
225 **                  NFCSTATUS_SUCCESS - CheckIntegrity request is successful
226 **                  NFCSTATUS_FAILED - CheckIntegrity request failed due to
227 **                                     internal error
228 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
229 **                  Other command specific errors
230 **
231 *******************************************************************************/
phDnldNfc_CheckIntegrity(uint8_t bChipVer,pphDnldNfc_Buff_t pCRCData,pphDnldNfc_RspCb_t pNotify,void * pContext)232 NFCSTATUS phDnldNfc_CheckIntegrity(uint8_t bChipVer, pphDnldNfc_Buff_t pCRCData,
233                                    pphDnldNfc_RspCb_t pNotify, void* pContext) {
234   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
235 
236   if ((NULL == pNotify) || (NULL == pContext)) {
237     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
238     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
239   } else {
240     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
241       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
242       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
243     } else {
244       if ((PHDNLDNFC_HWVER_MRA2_1 == bChipVer) ||
245           (PHDNLDNFC_HWVER_MRA2_2 == bChipVer) ||
246           ((nfcFL.chipType == pn551) &&
247            (PHDNLDNFC_HWVER_PN551_MRA1_0 == bChipVer)) ||
248           (((nfcFL.chipType == pn553) || (nfcFL.chipType == pn557)) &&
249            ((PHDNLDNFC_HWVER_PN553_MRA1_0 == bChipVer) ||
250             (PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & bChipVer) ||
251             (PHDNLDNFC_HWVER_PN557_MRA1_0 == bChipVer)))) {
252         (gpphDnldContext->FrameInp.Type) = phDnldNfc_ChkIntg;
253       } else {
254         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
255       }
256 
257       if ((NULL != pCRCData->pBuff) && (0 != pCRCData->wLen)) {
258         (gpphDnldContext->tRspBuffInfo.pBuff) = pCRCData->pBuff;
259         (gpphDnldContext->tRspBuffInfo.wLen) = pCRCData->wLen;
260         (gpphDnldContext->tCmdId) = PH_DL_CMD_CHECKINTEGRITY;
261         (gpphDnldContext->tUserData.pBuff) = NULL;
262         (gpphDnldContext->tUserData.wLen) = 0;
263         (gpphDnldContext->UserCb) = pNotify;
264         (gpphDnldContext->UserCtxt) = pContext;
265 
266         wStatus =
267             phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventIntegChk);
268 
269         if (NFCSTATUS_PENDING == wStatus) {
270           NXPLOG_FWDNLD_D("CheckIntegrity Request submitted successfully");
271         } else {
272           NXPLOG_FWDNLD_E("CheckIntegrity Request Failed!!");
273         }
274       } else {
275         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
276         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
277       }
278     }
279   }
280 
281   return wStatus;
282 }
283 /*******************************************************************************
284 **
285 ** Function         phDnldNfc_ReadLog
286 **
287 ** Description      Retrieves log data from EEPROM
288 **
289 ** Parameters       pData - response buffer which gets updated with data from
290 **                          EEPROM
291 **                  pNotify - notify caller after getting response
292 **                  pContext - caller context
293 **
294 ** Returns          NFC status:
295 **                  NFCSTATUS_SUCCESS - Read request to NFCC is successful
296 **                  NFCSTATUS_FAILED - Read request failed due to internal error
297 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
298 **                  Other command specific errors
299 **
300 *******************************************************************************/
phDnldNfc_ReadLog(pphDnldNfc_Buff_t pData,pphDnldNfc_RspCb_t pNotify,void * pContext)301 NFCSTATUS phDnldNfc_ReadLog(pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify,
302                             void* pContext) {
303   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
304 
305   if ((NULL == pNotify) || (NULL == pData) || (NULL == pContext)) {
306     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
307     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
308   } else {
309     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
310       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
311       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
312     } else {
313       if ((NULL != pData->pBuff) && (0 != pData->wLen)) {
314         (gpphDnldContext->tCmdId) = PH_DL_CMD_READ;
315         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRead;
316         (gpphDnldContext->FrameInp.dwAddr) = PHDNLDNFC_EEPROM_LOG_START_ADDR;
317         (gpphDnldContext->tRspBuffInfo.pBuff) = pData->pBuff;
318         (gpphDnldContext->tRspBuffInfo.wLen) = pData->wLen;
319         (gpphDnldContext->tUserData.pBuff) = NULL;
320         (gpphDnldContext->tUserData.wLen) = 0;
321         (gpphDnldContext->UserCb) = pNotify;
322         (gpphDnldContext->UserCtxt) = pContext;
323 
324         memset(&(gpphDnldContext->tRWInfo), 0,
325                sizeof(gpphDnldContext->tRWInfo));
326 
327         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventRead);
328 
329         if (NFCSTATUS_PENDING == wStatus) {
330           NXPLOG_FWDNLD_D("Read Request submitted successfully");
331         } else {
332           NXPLOG_FWDNLD_E("Read Request Failed!!");
333         }
334       } else {
335         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
336         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
337       }
338     }
339   }
340 
341   return wStatus;
342 }
343 
344 /*******************************************************************************
345 **
346 ** Function         phDnldNfc_Write
347 **
348 ** Description      Writes requested  data of length len to desired EEPROM/FLASH
349 **                  address
350 **
351 ** Parameters       bRecoverSeq - flag to indicate whether recover sequence data
352 **                                needs to be written or not
353 **                  pData - data buffer to write into EEPROM/FLASH by user
354 **                  pNotify - notify caller after getting response
355 **                  pContext - caller context
356 **
357 ** Returns          NFC status:
358 **                  NFCSTATUS_SUCCESS - Write request to NFCC is successful
359 **                  NFCSTATUS_FAILED - Write request failed due to internal
360 **                                     error
361 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
362 **                  Other command specific errors
363 **
364 *******************************************************************************/
phDnldNfc_Write(bool_t bRecoverSeq,pphDnldNfc_Buff_t pData,pphDnldNfc_RspCb_t pNotify,void * pContext)365 NFCSTATUS phDnldNfc_Write(bool_t bRecoverSeq, pphDnldNfc_Buff_t pData,
366                           pphDnldNfc_RspCb_t pNotify, void* pContext) {
367   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
368   uint8_t* pImgPtr = NULL;
369   uint16_t wLen = 0;
370   phDnldNfc_Buff_t tImgBuff;
371 
372   if ((NULL == pNotify) || (NULL == pContext)) {
373     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
374     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
375   } else {
376     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
377       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
378       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
379     } else {
380       if (NULL != pData) {
381         pImgPtr = pData->pBuff;
382         wLen = pData->wLen;
383       } else {
384         if (bRecoverSeq == false) {
385           pImgPtr = (uint8_t*)gpphDnldContext->nxp_nfc_fw;
386           wLen = gpphDnldContext->nxp_nfc_fw_len;
387 
388         } else {
389           if (PH_DL_STATUS_PLL_ERROR == (gpphDnldContext->tLastStatus)) {
390             wStatus = phDnldNfc_LoadRecInfo();
391           } else if (PH_DL_STATUS_SIGNATURE_ERROR ==
392                      (gpphDnldContext->tLastStatus)) {
393             wStatus = phDnldNfc_LoadPKInfo();
394           } else {
395           }
396 
397           if (NFCSTATUS_SUCCESS == wStatus) {
398             pImgPtr = (uint8_t*)gpphDnldContext->nxp_nfc_fwp;
399             wLen = gpphDnldContext->nxp_nfc_fwp_len;
400           } else {
401             NXPLOG_FWDNLD_E("Platform Recovery Image extraction Failed!!");
402             pImgPtr = NULL;
403             wLen = 0;
404           }
405         }
406       }
407 
408       if ((NULL != pImgPtr) && (0 != wLen)) {
409         tImgBuff.pBuff = pImgPtr;
410         tImgBuff.wLen = wLen;
411 
412         (gpphDnldContext->tCmdId) = PH_DL_CMD_WRITE;
413         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTWrite;
414         (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
415         (gpphDnldContext->tRspBuffInfo.wLen) = 0;
416         (gpphDnldContext->tUserData.pBuff) = pImgPtr;
417         (gpphDnldContext->tUserData.wLen) = wLen;
418         (gpphDnldContext->bResendLastFrame) = false;
419 
420         memset(&(gpphDnldContext->tRWInfo), 0,
421                sizeof(gpphDnldContext->tRWInfo));
422         (gpphDnldContext->tRWInfo.bFirstWrReq) = true;
423         (gpphDnldContext->UserCb) = pNotify;
424         (gpphDnldContext->UserCtxt) = pContext;
425 
426         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventWrite);
427 
428         if (NFCSTATUS_PENDING == wStatus) {
429           NXPLOG_FWDNLD_D("Write Request submitted successfully");
430         } else {
431           NXPLOG_FWDNLD_E("Write Request Failed!!");
432         }
433       } else {
434         NXPLOG_FWDNLD_E("Download Image Primitives extraction failed!!");
435         wStatus = NFCSTATUS_FAILED;
436       }
437     }
438   }
439 
440   return wStatus;
441 }
442 
443 /*******************************************************************************
444 **
445 ** Function         phDnldNfc_Log
446 **
447 ** Description      Provides a full page free write to EEPROM
448 **
449 ** Parameters       pData - data buffer to write into EEPROM/FLASH by user
450 **                  pNotify - notify caller after getting response
451 **                  pContext - caller context
452 **
453 ** Returns          NFC status:
454 **                  NFCSTATUS_SUCCESS - Write request to NFCC is successful
455 **                  NFCSTATUS_FAILED - Write request failed due to internal
456 **                                     error
457 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
458 **                  Other command specific error
459 **
460 *******************************************************************************/
phDnldNfc_Log(pphDnldNfc_Buff_t pData,pphDnldNfc_RspCb_t pNotify,void * pContext)461 NFCSTATUS phDnldNfc_Log(pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify,
462                         void* pContext) {
463   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
464 
465   if ((NULL == pNotify) || (NULL == pData) || (NULL == pContext)) {
466     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
467     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
468   } else {
469     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
470       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
471       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
472     } else {
473       if ((NULL != (pData->pBuff)) &&
474           ((0 != (pData->wLen) && (PHDNLDNFC_MAX_LOG_SIZE >= (pData->wLen))))) {
475         (gpphDnldContext->tCmdId) = PH_DL_CMD_LOG;
476         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTLog;
477         (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
478         (gpphDnldContext->tRspBuffInfo.wLen) = 0;
479         (gpphDnldContext->tUserData.pBuff) = (pData->pBuff);
480         (gpphDnldContext->tUserData.wLen) = (pData->wLen);
481 
482         memset(&(gpphDnldContext->tRWInfo), 0,
483                sizeof(gpphDnldContext->tRWInfo));
484         (gpphDnldContext->UserCb) = pNotify;
485         (gpphDnldContext->UserCtxt) = pContext;
486 
487         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventLog);
488 
489         if (NFCSTATUS_PENDING == wStatus) {
490           NXPLOG_FWDNLD_D("Log Request submitted successfully");
491         } else {
492           NXPLOG_FWDNLD_E("Log Request Failed!!");
493         }
494       } else {
495         NXPLOG_FWDNLD_E("Invalid Input Parameters for Log!!");
496         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
497       }
498     }
499   }
500 
501   return wStatus;
502 }
503 
504 /*******************************************************************************
505 **
506 ** Function         phDnldNfc_Force
507 **
508 ** Description      Used as an emergency recovery procedure for NFCC due to
509 **                  corrupt settings of system platform specific parameters by
510 **                  the host
511 **
512 ** Parameters       pInputs - input buffer which contains  clk src & clk freq
513 **                            settings for desired platform
514 **                  pNotify - notify caller after getting response
515 **                  pContext - caller context
516 **
517 ** Returns          NFC status:
518 **                  NFCSTATUS_SUCCESS - Emergency Recovery request is successful
519 **                  NFCSTATUS_FAILED - Emergency Recovery failed due to internal
520 **                                     error
521 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
522 **                  Other command specific errors
523 **
524 *******************************************************************************/
phDnldNfc_Force(pphDnldNfc_Buff_t pInputs,pphDnldNfc_RspCb_t pNotify,void * pContext)525 NFCSTATUS phDnldNfc_Force(pphDnldNfc_Buff_t pInputs, pphDnldNfc_RspCb_t pNotify,
526                           void* pContext) {
527   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
528   uint8_t bClkSrc = 0x00, bClkFreq = 0x00;
529   uint8_t bPldVal[3] = {
530       0x11, 0x00, 0x00}; /* default values to be used if input not provided */
531 
532   if ((NULL == pNotify) || (NULL == pContext)) {
533     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
534     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
535   } else {
536     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
537       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
538       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
539     } else {
540       (gpphDnldContext->tCmdId) = PH_DL_CMD_FORCE;
541       (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTForce;
542       (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
543       (gpphDnldContext->tRspBuffInfo.wLen) = 0;
544 
545       if ((0 != (pInputs->wLen)) || (NULL != (pInputs->pBuff))) {
546         if (CLK_SRC_XTAL == (pInputs->pBuff[0])) {
547           bClkSrc = phDnldNfc_ClkSrcXtal;
548         } else if (CLK_SRC_PLL == (pInputs->pBuff[0])) {
549           bClkSrc = phDnldNfc_ClkSrcPLL;
550           if (CLK_FREQ_13MHZ == (pInputs->pBuff[1])) {
551             bClkFreq = phDnldNfc_ClkFreq_13Mhz;
552           } else if (CLK_FREQ_19_2MHZ == (pInputs->pBuff[1])) {
553             bClkFreq = phDnldNfc_ClkFreq_19_2Mhz;
554           } else if (CLK_FREQ_24MHZ == (pInputs->pBuff[1])) {
555             bClkFreq = phDnldNfc_ClkFreq_24Mhz;
556           } else if (CLK_FREQ_26MHZ == (pInputs->pBuff[1])) {
557             bClkFreq = phDnldNfc_ClkFreq_26Mhz;
558           } else if (CLK_FREQ_38_4MHZ == (pInputs->pBuff[1])) {
559             bClkFreq = phDnldNfc_ClkFreq_38_4Mhz;
560           } else if (CLK_FREQ_52MHZ == (pInputs->pBuff[1])) {
561             bClkFreq = phDnldNfc_ClkFreq_52Mhz;
562           } else {
563             NXPLOG_FWDNLD_E(
564                 "Invalid Clk Frequency !! Using default value of 19.2Mhz..");
565             bClkFreq = phDnldNfc_ClkFreq_19_2Mhz;
566           }
567 
568         } else if (CLK_SRC_PADDIRECT == (pInputs->pBuff[0])) {
569           bClkSrc = phDnldNfc_ClkSrcPad;
570         } else {
571           NXPLOG_FWDNLD_E("Invalid Clk src !! Using default value of PLL..");
572           bClkSrc = phDnldNfc_ClkSrcPLL;
573         }
574 
575         bPldVal[0] = 0U;
576         bPldVal[0] = ((bClkSrc << 3U) | bClkFreq);
577       } else {
578         NXPLOG_FWDNLD_E("Clk src inputs not provided!! Using default values..");
579       }
580 
581       (gpphDnldContext->tUserData.pBuff) = bPldVal;
582       (gpphDnldContext->tUserData.wLen) = sizeof(bPldVal);
583 
584       memset(&(gpphDnldContext->tRWInfo), 0, sizeof(gpphDnldContext->tRWInfo));
585       (gpphDnldContext->UserCb) = pNotify;
586       (gpphDnldContext->UserCtxt) = pContext;
587 
588       wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventForce);
589 
590       if (NFCSTATUS_PENDING == wStatus) {
591         NXPLOG_FWDNLD_D("Force Command Request submitted successfully");
592       } else {
593         NXPLOG_FWDNLD_E("Force Command Request Failed!!");
594       }
595     }
596   }
597 
598   return wStatus;
599 }
600 
601 /*******************************************************************************
602 **
603 ** Function         phDnldNfc_SetHwDevHandle
604 **
605 ** Description      Stores the HwDev handle to download context. The handle is
606 **                  required for subsequent operations
607 **
608 ** Parameters       None
609 **
610 ** Returns          None                -
611 **
612 *******************************************************************************/
phDnldNfc_SetHwDevHandle(void)613 void phDnldNfc_SetHwDevHandle(void) {
614   pphDnldNfc_DlContext_t psDnldContext = NULL;
615 
616   if (NULL == gpphDnldContext) {
617     NXPLOG_FWDNLD_D("Allocating Mem for Dnld Context..");
618     /* Create the memory for Download Mgmt Context */
619     psDnldContext =
620         (pphDnldNfc_DlContext_t)malloc(sizeof(phDnldNfc_DlContext_t));
621 
622     if (psDnldContext != NULL) {
623       (void)memset((void*)psDnldContext, 0, sizeof(phDnldNfc_DlContext_t));
624       gpphDnldContext = psDnldContext;
625     } else {
626       NXPLOG_FWDNLD_E("Error Allocating Mem for Dnld Context..")
627     }
628   } else {
629     (void)memset((void*)gpphDnldContext, 0, sizeof(phDnldNfc_DlContext_t));
630   }
631   return;
632 }
633 
634 /*******************************************************************************
635 **
636 ** Function         phDnldNfc_ReSetHwDevHandle
637 **
638 ** Description      Frees the HwDev handle to download context.
639 **
640 ** Parameters       None
641 **
642 ** Returns          None                -
643 **
644 *******************************************************************************/
phDnldNfc_ReSetHwDevHandle(void)645 void phDnldNfc_ReSetHwDevHandle(void) {
646   if (gpphDnldContext != NULL) {
647     NXPLOG_FWDNLD_D("Freeing Mem for Dnld Context..")
648     free(gpphDnldContext);
649     gpphDnldContext = NULL;
650   }
651 }
652 
653 /*******************************************************************************
654 **
655 ** Function         phDnldNfc_RawReq
656 **
657 ** Description      Sends raw frame request to NFCC.
658 **                  It is currently used for sending an NCI RESET cmd after
659 **                  doing a production key update
660 **
661 ** Parameters       pFrameData - input buffer, contains raw frame packet to be
662 **                               sent to NFCC
663 **                  pRspData - response buffer received from NFCC
664 **                  pNotify - notify caller after getting response
665 **                  pContext - caller context
666 **
667 ** Returns          NFC status:
668 **                  NFCSTATUS_SUCCESS - GetSessionState request to NFCC is
669 **                                      successful
670 **                  NFCSTATUS_FAILED - GetSessionState request failed due to
671 **                                     internal error
672 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
673 **                  Other command specific errors
674 **
675 *******************************************************************************/
phDnldNfc_RawReq(pphDnldNfc_Buff_t pFrameData,pphDnldNfc_Buff_t pRspData,pphDnldNfc_RspCb_t pNotify,void * pContext)676 NFCSTATUS phDnldNfc_RawReq(pphDnldNfc_Buff_t pFrameData,
677                            pphDnldNfc_Buff_t pRspData,
678                            pphDnldNfc_RspCb_t pNotify, void* pContext) {
679   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
680 
681   if ((NULL == pFrameData) || (NULL == pNotify) || (NULL == pRspData) ||
682       (NULL == pContext)) {
683     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
684     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
685   } else {
686     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
687       NXPLOG_FWDNLD_E("Raw Cmd Request in Progress..Cannot Continue!!");
688       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
689     } else {
690       if (((NULL != pFrameData->pBuff) && (0 != pFrameData->wLen)) &&
691           ((NULL != pRspData->pBuff) && (0 != pRspData->wLen))) {
692         (gpphDnldContext->tRspBuffInfo.pBuff) = pRspData->pBuff;
693         (gpphDnldContext->tRspBuffInfo.wLen) = pRspData->wLen;
694         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRaw;
695         (gpphDnldContext->tCmdId) = PH_DL_CMD_NONE;
696         (gpphDnldContext->tUserData.pBuff) = pFrameData->pBuff;
697         (gpphDnldContext->tUserData.wLen) = pFrameData->wLen;
698         (gpphDnldContext->UserCb) = pNotify;
699         (gpphDnldContext->UserCtxt) = pContext;
700 
701         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventRaw);
702 
703         if (NFCSTATUS_PENDING == wStatus) {
704           NXPLOG_FWDNLD_D("RawFrame Request submitted successfully");
705         } else {
706           NXPLOG_FWDNLD_E("RawFrame Request Failed!!");
707         }
708       } else {
709         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
710         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
711       }
712     }
713   }
714 
715   return wStatus;
716 }
717 
718 /*******************************************************************************
719 **
720 ** Function         phDnldNfc_InitImgInfo
721 **
722 ** Description      Extracts image information and stores it in respective
723 **                  variables, to be used internally for write operation
724 **
725 ** Parameters       None
726 **
727 ** Returns          NFC status
728 **
729 *******************************************************************************/
phDnldNfc_InitImgInfo(void)730 NFCSTATUS phDnldNfc_InitImgInfo(void) {
731   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
732   uint8_t* pImageInfo = NULL;
733   uint16_t ImageInfoLen = 0;
734   unsigned long fwType = FW_FORMAT_SO;
735 
736   /* if memory is not allocated then allocate memory for download context
737    * structure */
738   phDnldNfc_SetHwDevHandle();
739 
740   gpphDnldContext->FwFormat = FW_FORMAT_UNKNOWN;
741 
742   /*Read Firmware file name from config file*/
743   if (GetNxpNumValue(NAME_NXP_FW_TYPE, &fwType, sizeof(fwType)) == true) {
744     NXPLOG_FWDNLD_D("firmware type from conf file: %lu",fwType);
745   } else {
746     NXPLOG_FWDNLD_W("firmware type not found. Taking default value: %lu",fwType);
747   }
748 
749   if(fwType == FW_FORMAT_BIN) {
750     gpphDnldContext->FwFormat = FW_FORMAT_BIN;
751     wStatus = phDnldNfc_LoadBinFW(&pImageInfo, &ImageInfoLen);
752   } else if(fwType == FW_FORMAT_SO) {
753     gpphDnldContext->FwFormat = FW_FORMAT_SO;
754     if (gRecFWDwnld == true) {
755       wStatus = phDnldNfc_LoadRecoveryFW(&pImageInfo, &ImageInfoLen);
756     } else {
757       wStatus = phDnldNfc_LoadFW(&pImageInfo, &ImageInfoLen);
758     }
759   } else {
760     NXPLOG_FWDNLD_E("firmware file format mismatch!!!\n");
761     return NFCSTATUS_FAILED;
762   }
763 
764   NXPLOG_FWDNLD_D("FW Image Length - ImageInfoLen %d", ImageInfoLen);
765   NXPLOG_FWDNLD_D("FW Image Info Pointer - pImageInfo %p", pImageInfo);
766 
767   if ((pImageInfo == NULL) || (ImageInfoLen == 0)) {
768     NXPLOG_FWDNLD_E(
769         "Image extraction Failed - invalid imginfo or imginfolen!!");
770     wStatus = NFCSTATUS_FAILED;
771   }
772 
773   if (wStatus != NFCSTATUS_SUCCESS) {
774     NXPLOG_FWDNLD_E("Error loading libpn54x_fw !!\n");
775   }
776 
777   /* get the MW version */
778   if (NFCSTATUS_SUCCESS == wStatus) {
779     // NXPLOG_FWDNLD_D("MW Major Version Num - %x",NXP_MW_VERSION_MAJ);
780     // NXPLOG_FWDNLD_D("MW Minor Version Num - %x",NXP_MW_VERSION_MIN);
781     wMwVer = (((uint16_t)(NXP_MW_VERSION_MAJ) << 8U) | (NXP_MW_VERSION_MIN));
782   }
783 
784   if (NFCSTATUS_SUCCESS == wStatus) {
785     gpphDnldContext->nxp_nfc_fw = (uint8_t*)pImageInfo;
786     gpphDnldContext->nxp_nfc_fw_len = ImageInfoLen;
787     if ((NULL != gpphDnldContext->nxp_nfc_fw) &&
788         (0 != gpphDnldContext->nxp_nfc_fw_len)) {
789       NXPLOG_FWDNLD_D("FW Major Version Num - %x",
790                       gpphDnldContext->nxp_nfc_fw[5]);
791       NXPLOG_FWDNLD_D("FW Minor Version Num - %x",
792                       gpphDnldContext->nxp_nfc_fw[4]);
793       NXPLOG_FWDNLD_D("FW Image Length - %d", ImageInfoLen);
794       NXPLOG_FWDNLD_D("FW Image Info Pointer - %p", pImageInfo);
795 
796       /* get the FW version */
797       wFwVer = (((uint16_t)(gpphDnldContext->nxp_nfc_fw[5]) << 8U) |
798                 (gpphDnldContext->nxp_nfc_fw[4]));
799       wStatus = NFCSTATUS_SUCCESS;
800     } else {
801       NXPLOG_FWDNLD_E("Image details extraction Failed!!");
802       wStatus = NFCSTATUS_FAILED;
803     }
804   }
805 
806   return wStatus;
807 }
808 
809 /*******************************************************************************
810 **
811 ** Function         phDnldNfc_LoadRecInfo
812 **
813 ** Description      Extracts recovery sequence image information and stores it
814 **                  in respective variables, to be used internally for write
815 **                  operation
816 **
817 ** Parameters       None
818 **
819 ** Returns          NFC status
820 **
821 *******************************************************************************/
phDnldNfc_LoadRecInfo(void)822 NFCSTATUS phDnldNfc_LoadRecInfo(void) {
823   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
824   uint8_t* pImageInfo = NULL;
825   uint16_t ImageInfoLen = 0;
826 
827   /* if memory is not allocated then allocate memory for donwload context
828    * structure */
829   phDnldNfc_SetHwDevHandle();
830   if (gRecFWDwnld == true)
831     wStatus = phDnldNfc_LoadRecoveryFW(&pImageInfo, &ImageInfoLen);
832   else
833     wStatus = phDnldNfc_LoadFW(&pImageInfo, &ImageInfoLen);
834 
835   if ((pImageInfo == NULL) || (ImageInfoLen == 0)) {
836     NXPLOG_FWDNLD_E(
837         "Image extraction Failed - invalid imginfo or imginfolen!!");
838     wStatus = NFCSTATUS_FAILED;
839   }
840 
841   /* load the PLL recovery image library */
842   if (wStatus != NFCSTATUS_SUCCESS) {
843     NXPLOG_FWDNLD_E("Error loading libpn54x_fw_platform !!\n");
844   }
845 
846   if (NFCSTATUS_SUCCESS == wStatus) {
847     /* fetch the PLL recovery image pointer and the image length */
848     gpphDnldContext->nxp_nfc_fwp = (uint8_t*)pImageInfo;
849     gpphDnldContext->nxp_nfc_fwp_len = ImageInfoLen;
850     if ((NULL != gpphDnldContext->nxp_nfc_fwp) &&
851         (0 != gpphDnldContext->nxp_nfc_fwp_len)) {
852       NXPLOG_FWDNLD_D("Recovery Image Length - %d", ImageInfoLen);
853       NXPLOG_FWDNLD_D("Recovery Image Info Pointer - %p", pImageInfo);
854       wStatus = NFCSTATUS_SUCCESS;
855     } else {
856       NXPLOG_FWDNLD_E("Recovery Image details extraction Failed!!");
857       wStatus = NFCSTATUS_FAILED;
858     }
859   }
860 
861   return wStatus;
862 }
863 
864 /*******************************************************************************
865 **
866 ** Function         phDnldNfc_LoadPKInfo
867 **
868 ** Description      Extracts production sequence image information and stores it
869 **                  in respective variables, to be used internally for write
870 **                  operation
871 **
872 ** Parameters       None
873 **
874 ** Returns          NFC status
875 **
876 *******************************************************************************/
phDnldNfc_LoadPKInfo(void)877 NFCSTATUS phDnldNfc_LoadPKInfo(void) {
878   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
879   uint8_t* pImageInfo = NULL;
880   uint16_t ImageInfoLen = 0;
881 
882   /* if memory is not allocated then allocate memory for donwload context
883    * structure */
884   phDnldNfc_SetHwDevHandle();
885   /* load the PKU image library */
886   if (gRecFWDwnld == true)
887     wStatus = phDnldNfc_LoadRecoveryFW(&pImageInfo, &ImageInfoLen);
888   else
889     wStatus = phDnldNfc_LoadFW(&pImageInfo, &ImageInfoLen);
890   if ((pImageInfo == NULL) || (ImageInfoLen == 0)) {
891     NXPLOG_FWDNLD_E(
892         "Image extraction Failed - invalid imginfo or imginfolen!!");
893     wStatus = NFCSTATUS_FAILED;
894   }
895 
896   if (wStatus != NFCSTATUS_SUCCESS) {
897     NXPLOG_FWDNLD_E("Error loading libpn54x_fw_pku !!\n");
898   }
899 
900   if (NFCSTATUS_SUCCESS == wStatus) {
901     /* fetch the PKU image pointer and the image length */
902     gpphDnldContext->nxp_nfc_fwp = (uint8_t*)pImageInfo;
903     gpphDnldContext->nxp_nfc_fwp_len = ImageInfoLen;
904 
905     if ((NULL != gpphDnldContext->nxp_nfc_fwp) &&
906         (0 != gpphDnldContext->nxp_nfc_fwp_len)) {
907       NXPLOG_FWDNLD_D("PKU Image Length - %d", ImageInfoLen);
908       NXPLOG_FWDNLD_D("PKU Image Info Pointer - %p", pImageInfo);
909       wStatus = NFCSTATUS_SUCCESS;
910     } else {
911       NXPLOG_FWDNLD_E("PKU Image details extraction Failed!!");
912       wStatus = NFCSTATUS_FAILED;
913     }
914   }
915 
916   return wStatus;
917 }
918 
919 /*******************************************************************************
920 **
921 ** Function         phDnldNfc_CloseFwLibHandle
922 **
923 ** Description      Closes previously opened fw library handle as part of
924 **                  dynamic loader processing
925 **
926 ** Parameters       None
927 **
928 ** Returns          None
929 **
930 *******************************************************************************/
phDnldNfc_CloseFwLibHandle(void)931 void phDnldNfc_CloseFwLibHandle(void) {
932   NFCSTATUS wStatus = NFCSTATUS_FAILED;
933   if (gpphDnldContext->FwFormat == FW_FORMAT_SO) {
934     wStatus = phDnldNfc_UnloadFW();
935     if (wStatus != NFCSTATUS_SUCCESS) {
936       NXPLOG_FWDNLD_E("free library FAILED !!\n");
937     } else {
938       NXPLOG_FWDNLD_E("free library SUCCESS !!\n");
939     }
940   } else if (gpphDnldContext->FwFormat == FW_FORMAT_BIN) {
941     if (pFwHandle != NULL) {
942       free(pFwHandle);
943       pFwHandle = NULL;
944     }
945   }
946   return;
947 }
948 
949 /*******************************************************************************
950 **
951 ** Function         phDnldNfc_LoadFW
952 **
953 ** Description      Load the firmware version form firmware lib
954 **
955 ** Parameters       pImgInfo    - Firmware image handle
956 **                  pImgInfoLen - Firmware image length
957 **
958 ** Returns          NFC status
959 **
960 *******************************************************************************/
phDnldNfc_LoadFW(uint8_t ** pImgInfo,uint16_t * pImgInfoLen)961 NFCSTATUS phDnldNfc_LoadFW(uint8_t** pImgInfo, uint16_t* pImgInfoLen) {
962   void* pImageInfo = NULL;
963   void* pImageInfoLen = NULL;
964 
965   /* check if the handle is not NULL then free the library */
966   if (pFwHandle != NULL) {
967     phDnldNfc_CloseFwLibHandle();
968     pFwHandle = NULL;
969   }
970 
971   /* load the DLL file */
972   pFwHandle = dlopen(nfcFL._FW_LIB_PATH.c_str(), RTLD_LAZY);
973   NXPLOG_FWDNLD_D("@@@%s", nfcFL._FW_LIB_PATH.c_str());
974 
975   /* if library load failed then handle will be NULL */
976   if (pFwHandle == NULL) {
977     NXPLOG_FWDNLD_E(
978         "NULL handler : unable to load the library file, specify correct path");
979     return NFCSTATUS_FAILED;
980   }
981 
982   dlerror(); /* Clear any existing error */
983 
984   /* load the address of download image pointer and image size */
985   pImageInfo = (void*)dlsym(pFwHandle, "gphDnldNfc_DlSeq");
986 
987   if (dlerror() || (NULL == pImageInfo)) {
988     NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeq");
989     return NFCSTATUS_FAILED;
990   }
991   (*pImgInfo) = (*(uint8_t**)pImageInfo);
992 
993   pImageInfoLen = (void*)dlsym(pFwHandle, "gphDnldNfc_DlSeqSz");
994   if (dlerror() || (NULL == pImageInfoLen)) {
995     NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeqSz");
996     return NFCSTATUS_FAILED;
997   }
998 
999   (*pImgInfoLen) = (uint16_t)(*((uint16_t*)pImageInfoLen));
1000 
1001   return NFCSTATUS_SUCCESS;
1002 }
1003 
1004 /*******************************************************************************
1005 **
1006 ** Function         phDnldNfc_LoadBinFW
1007 **
1008 ** Description      Load the firmware version form firmware lib
1009 **
1010 ** Parameters       pImgInfo    - Firmware image handle
1011 **                  pImgInfoLen - Firmware image length
1012 **
1013 ** Returns          NFC status
1014 **
1015 *******************************************************************************/
phDnldNfc_LoadBinFW(uint8_t ** pImgInfo,uint16_t * pImgInfoLen)1016 NFCSTATUS phDnldNfc_LoadBinFW(uint8_t** pImgInfo, uint16_t* pImgInfoLen) {
1017   FILE* pFile = NULL;
1018   uint32_t fileSize = 0;
1019   uint32_t bytesRead = 0;
1020   long ftellFileSize = 0;
1021 
1022   /* check for path name */
1023   if (nfcFL._FW_BIN_PATH.c_str() == NULL) {
1024     NXPLOG_FWDNLD_E("Invalid FW file path!!!\n");
1025     return NFCSTATUS_FAILED;
1026   }
1027 
1028   /* check if the handle is not NULL then free the memory*/
1029   if (pFwHandle != NULL) {
1030     phDnldNfc_CloseFwLibHandle();
1031     pFwHandle = NULL;
1032   }
1033 
1034   /* Open the FW binary image file to be read */
1035   pFile = fopen(nfcFL._FW_BIN_PATH.c_str(), "r");
1036   if (NULL == pFile) {
1037     NXPLOG_FWDNLD_E("Failed to load FW binary image file!!!\n");
1038     return NFCSTATUS_FAILED;
1039   }
1040 
1041   /* Seek to the end of the file */
1042   fseek(pFile, 0, SEEK_END);
1043 
1044   /* get the actual length of the file */
1045   ftellFileSize = ftell(pFile);
1046 
1047   if (ftellFileSize > 0) {
1048     fileSize = ftellFileSize;
1049   } else {
1050     fileSize = 0;
1051   }
1052 
1053   /* Seek to the start of the file, to move file handle back to start of file*/
1054   fseek(pFile, 0, SEEK_SET);
1055 
1056   /* allocate the memory to read the FW binary image */
1057   pFwHandle = (void*)malloc(sizeof(uint8_t) * fileSize);
1058 
1059   /* check for valid memory allocation */
1060   if (NULL == pFwHandle) {
1061     NXPLOG_FWDNLD_E("Failed to allocate memory to load FW image !!!\n");
1062     fclose(pFile);
1063     return NFCSTATUS_FAILED;
1064   }
1065 
1066   /* Read the actual contents of the FW binary image */
1067   bytesRead =
1068       (uint32_t)fread(pFwHandle, sizeof(uint8_t), (size_t)fileSize, pFile);
1069   if (bytesRead != fileSize) {
1070     NXPLOG_FWDNLD_E("Unable to read the specified size from file !!!\n");
1071     fclose(pFile);
1072     free(pFwHandle);
1073     pFwHandle = NULL;
1074     return NFCSTATUS_FAILED;
1075   }
1076 
1077   /* Update the image info pointer to the caller */
1078   *pImgInfo = (uint8_t*)pFwHandle;
1079   *pImgInfoLen = (uint16_t)(bytesRead & 0xFFFF);
1080 
1081   /* close the FW binary image file */
1082   fclose(pFile);
1083   return NFCSTATUS_SUCCESS;
1084 }
1085 
1086 /*******************************************************************************
1087 **
1088 ** Function         phDnldNfc_LoadRecoveryFW
1089 **
1090 ** Description      Load the dummy firmware version form firmware lib for
1091 **                  recovery. This will change the FW version of the NFCC
1092 **                  firmware and enable flashing of firmware of same version.
1093 **
1094 ** Parameters       pImgInfo    - Firmware image handle
1095 **                  pImgInfoLen - Firmware image length
1096 **
1097 ** Returns          NFCSTATUS
1098 **
1099 *******************************************************************************/
phDnldNfc_LoadRecoveryFW(uint8_t ** pImgInfo,uint16_t * pImgInfoLen)1100 NFCSTATUS phDnldNfc_LoadRecoveryFW(uint8_t** pImgInfo, uint16_t* pImgInfoLen) {
1101   void* pImageInfo = NULL;
1102   void* pImageInfoLen = NULL;
1103 
1104   /* check if the handle is not NULL then free the library */
1105   if (pFwHandle != NULL) {
1106     phDnldNfc_CloseFwLibHandle();
1107     pFwHandle = NULL;
1108   }
1109   /* load the DLL file */
1110   pFwHandle = dlopen(nfcFL._FW_LIB_PATH.c_str(), RTLD_LAZY);
1111   NXPLOG_FWDNLD_D("phDnldNfc_LoadRecoveryFW %s ", nfcFL._FW_LIB_PATH.c_str());
1112 
1113   /* if library load failed then handle will be NULL */
1114   if (pFwHandle == NULL) {
1115     NXPLOG_FWDNLD_E(
1116         "NULL handler : unable to load the library file, specify correct path");
1117     return NFCSTATUS_FAILED;
1118   }
1119 
1120   dlerror(); /* Clear any existing error */
1121 
1122   /* load the address of download image pointer and image size */
1123   pImageInfo = (void*)dlsym(pFwHandle, "gphDnldNfc_DummyDlSeq");
1124 
1125   if (dlerror() || (NULL == pImageInfo)) {
1126     NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DummyDlSeq");
1127     return NFCSTATUS_FAILED;
1128   }
1129 
1130   (*pImgInfo) = (*(uint8_t**)pImageInfo);
1131   pImageInfoLen = (void*)dlsym(pFwHandle, "gphDnldNfc_DlSeqDummyFwSz");
1132   if (dlerror() || (NULL == pImageInfoLen)) {
1133     NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeqDummyFwSz");
1134     return NFCSTATUS_FAILED;
1135   }
1136 
1137   (*pImgInfoLen) = (uint16_t)(*((uint16_t*)pImageInfoLen));
1138 
1139   return NFCSTATUS_SUCCESS;
1140 }
1141 
1142 /*******************************************************************************
1143 **
1144 ** Function         phDnldNfc_UnloadFW
1145 **
1146 ** Description      Deinit the firmware handle
1147 **
1148 ** Parameters       None
1149 **
1150 ** Returns          NFC status
1151 **
1152 *******************************************************************************/
phDnldNfc_UnloadFW(void)1153 NFCSTATUS phDnldNfc_UnloadFW(void) {
1154   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
1155   int32_t status;
1156 
1157   /* check if the handle is not NULL then free the library */
1158   if (pFwHandle != NULL) {
1159     status = dlclose(pFwHandle);
1160     pFwHandle = NULL;
1161 
1162     dlerror(); /* Clear any existing error */
1163     if (status != 0) {
1164       wStatus = NFCSTATUS_FAILED;
1165       NXPLOG_FWDNLD_E("Free library file failed");
1166     }
1167   }
1168 
1169   return wStatus;
1170 }
1171 
1172 #ifdef EEPROM_Read_Mem_IMP
1173 static pphDnldNfc_RspCb_t UserCb; /* Upper layer call back function */
1174 static void* UserCtxt;            /* Pointer to upper layer context */
1175 /* Function prototype declaration */
1176 static void phDnldNfc_ReadComplete(void* pContext, NFCSTATUS status,
1177                                    void* pInfo);
1178 
1179 /*******************************************************************************
1180 **
1181 ** Function         phDnldNfc_ReadMem
1182 **
1183 ** Description      Dumps the contents of EEPROM. The handle is required for
1184 **                  subsequent operations
1185 **
1186 ** Parameters       pHwRef - pointer to the hardware device
1187 **                  pNotify - notify caller after getting response
1188 **                  pContext - caller context
1189 **
1190 ** Returns          NFC status:
1191 **                  NFCSTATUS_SUCCESS - request to NFCC is successful
1192 **                  NFCSTATUS_FAILED - request failed due to internal error
1193 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
1194 **                  Other command specific errors
1195 **
1196 *******************************************************************************/
phDnldNfc_ReadMem(void * pHwRef,pphDnldNfc_RspCb_t pNotify,void * pContext)1197 NFCSTATUS phDnldNfc_ReadMem(void* pHwRef, pphDnldNfc_RspCb_t pNotify,
1198                             void* pContext) {
1199   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
1200   uint32_t wAddr = 0x2011C0; /* eeprom platform specific area start address */
1201   uint32_t wRdAddr = 0;
1202   uint8_t* pAddr;
1203   static uint8_t bRdData[3519]; /* buffer to hold the read data */
1204   static phDnldNfc_Buff_t Data;
1205 
1206   if ((NULL == pNotify) || (NULL == pContext)) {
1207     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
1208     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
1209   } else {
1210     /* Call Tml Ioctl to enable download mode */
1211     wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
1212 
1213     if (NFCSTATUS_SUCCESS == wStatus) {
1214       /* Set the obtained device handle to download module */
1215       phDnldNfc_SetHwDevHandle();
1216     } else {
1217       wStatus = NFCSTATUS_FAILED;
1218     }
1219 
1220     if (NFCSTATUS_SUCCESS == wStatus) {
1221       pAddr = (uint8_t*)&wAddr;
1222 
1223       wRdAddr = (pAddr[3]);
1224       wRdAddr <<= 8;
1225       wRdAddr |= (pAddr[2]);
1226       wRdAddr <<= 8;
1227       wRdAddr |= (pAddr[1]);
1228       wRdAddr <<= 8;
1229       wRdAddr |= (pAddr[0]);
1230 
1231       Data.pBuff = bRdData;
1232       Data.wLen = sizeof(bRdData);
1233       UserCb = pNotify;
1234       UserCtxt = pContext;
1235 
1236       wStatus = phDnldNfc_Read(&Data, wRdAddr,
1237                                (pphDnldNfc_RspCb_t)phDnldNfc_ReadComplete,
1238                                gpphDnldContext);
1239     } else {
1240       Data.pBuff = NULL;
1241       Data.wLen = 0;
1242       wStatus = NFCSTATUS_FAILED;
1243     }
1244 
1245     if (NFCSTATUS_PENDING == wStatus) {
1246       NXPLOG_FWDNLD_D("Read Request submitted successfully..");
1247     } else {
1248       NXPLOG_FWDNLD_E("Read Request submission failed!!");
1249     }
1250   }
1251 
1252   return wStatus;
1253 }
1254 
1255 /*******************************************************************************
1256 **
1257 ** Function         phDnldNfc_ReadComplete
1258 **
1259 ** Description      Read complete
1260 **
1261 ** Parameters       pContext - caller layer context
1262 **                  status   - status of the transaction
1263 **                  pInfo    - transaction info
1264 **
1265 ** Returns          None
1266 **
1267 *******************************************************************************/
phDnldNfc_ReadComplete(void * pContext,NFCSTATUS status,void * pInfo)1268 static void phDnldNfc_ReadComplete(void* pContext, NFCSTATUS status,
1269                                    void* pInfo) {
1270   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
1271   UNUSED(pContext);
1272 
1273   /* Call Tml Ioctl to enable/restore normal mode */
1274   wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
1275 
1276   if (NFCSTATUS_SUCCESS == wStatus) {
1277     NXPLOG_FWDNLD_D("Read Done!!");
1278   }
1279 
1280   UserCb(&UserCtxt, status, pInfo);
1281 
1282   return;
1283 }
1284 
1285 /*******************************************************************************
1286 **
1287 ** Function         phDnldNfc_Read
1288 **
1289 ** Description      Retrieves requested data of specified length from desired
1290 **                  EEPROM address
1291 **
1292 ** Parameters       pData - response buffer which gets updated with data from
1293 **                          EEPROM
1294 **                  dwRdAddr - EEPROM address for data read
1295 **                  pNotify - notify caller after getting response
1296 **                  pContext - caller context
1297 **
1298 ** Returns          NFC status:
1299 **                  NFCSTATUS_SUCCESS - Read request to NFCC is successful
1300 **                  NFCSTATUS_FAILED - Read request failed due to internal error
1301 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
1302 **                  Other command specific errors
1303 **
1304 *******************************************************************************/
phDnldNfc_Read(pphDnldNfc_Buff_t pData,uint32_t dwRdAddr,pphDnldNfc_RspCb_t pNotify,void * pContext)1305 NFCSTATUS phDnldNfc_Read(pphDnldNfc_Buff_t pData, uint32_t dwRdAddr,
1306                          pphDnldNfc_RspCb_t pNotify, void* pContext) {
1307   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
1308 
1309   if ((NULL == pNotify) || (NULL == pData) || (NULL == pContext)) {
1310     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
1311     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
1312   } else {
1313     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
1314       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
1315       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
1316     } else {
1317       if ((NULL != pData->pBuff) && (0 != pData->wLen)) {
1318         (gpphDnldContext->tCmdId) = PH_DL_CMD_READ;
1319         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRead;
1320         (gpphDnldContext->FrameInp.dwAddr) = dwRdAddr;
1321         (gpphDnldContext->tRspBuffInfo.pBuff) = pData->pBuff;
1322         (gpphDnldContext->tRspBuffInfo.wLen) = pData->wLen;
1323         (gpphDnldContext->tUserData.pBuff) = NULL;
1324         (gpphDnldContext->tUserData.wLen) = 0;
1325         (gpphDnldContext->UserCb) = pNotify;
1326         (gpphDnldContext->UserCtxt) = pContext;
1327 
1328         memset(&(gpphDnldContext->tRWInfo), 0,
1329                sizeof(gpphDnldContext->tRWInfo));
1330 
1331         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventRead);
1332 
1333         if (NFCSTATUS_PENDING == wStatus) {
1334           NXPLOG_FWDNLD_D("Read Request submitted successfully");
1335         } else {
1336           NXPLOG_FWDNLD_E("Read Request Failed!!");
1337         }
1338       } else {
1339         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
1340         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
1341       }
1342     }
1343   }
1344 
1345   return wStatus;
1346 }
1347 #endif
1348