1 /******************************************************************************
2  *
3  *  Copyright (C) 2018 ST Microelectronics S.A.
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *
18  ******************************************************************************/
19 #define LOG_TAG "NfcHalFd"
20 #include "hal_fd.h"
21 #include <cutils/properties.h>
22 #include <dlfcn.h>
23 #include <errno.h>
24 #include <hardware/nfc.h>
25 #include <string.h>
26 #include "android_logmsg.h"
27 #include "halcore.h"
28 /* Initialize fw info structure pointer used to access fw info structure */
29 FWInfo *mFWInfo = NULL;
30 
31 FWCap *mFWCap = NULL;
32 
33 FILE *mFwFileBin;
34 FILE *mCustomFileBin;
35 fpos_t mPos;
36 fpos_t mPosInit;
37 uint8_t mBinData[260];
38 bool mRetry = true;
39 bool mCustomParamFailed = false;
40 bool mCustomParamDone = false;
41 bool mUwbConfigDone = false;
42 bool mUwbConfigNeeded = false;
43 bool mGetCustomerField = false;
44 uint8_t *pCmd;
45 int mFWRecovCount = 0;
46 const char *FwType = "generic";
47 char mApduAuthent[24];
48 
49 static const uint8_t propNfcModeSetCmdOn[] = {0x2f, 0x02, 0x02, 0x02, 0x01};
50 static const uint8_t coreInitCmd[] = {0x20, 0x01, 0x02, 0x00, 0x00};
51 static const uint8_t NciPropNfcFwUpdate[] = {0x2F, 0x02, 0x05, 0x06,
52                                              0x00, 0x01, 0x02, 0x03};
53 
54 static uint8_t ApduEraseNfcKeepAppliAndNdef[] = {
55     0x2F, 0x04, 0x16, 0x80, 0x0C, 0x00, 0x00, 0x11, 0x05,
56     0x00, 0x23, 0xDF, 0x00, 0x00, 0x23, 0xDF, 0xFF, 0x00,
57     0x23, 0xE0, 0x00, 0x00, 0x23, 0xFF, 0xFF};
58 
59 static const uint8_t ApduExitLoadMode[] = {0x2F, 0x04, 0x06, 0x80, 0xA0,
60                                            0x00, 0x00, 0x01, 0x01};
61 
62 // APDUs for ST54L
63 const int UK_NB = 2;
64 const int UK_SIZE = 12;
65 static uint8_t UserKeys[UK_NB][UK_SIZE] = {
66     {0x00, 0x00, 0xFD, 0x0F, 0x87, 0x7D, 0x31, 0xE3, 0xCF, 0x0C, 0xD3,
67      0x68},  // Test
68     {0x00, 0x00, 0xFD, 0x00, 0x87, 0x7D, 0x31, 0xE3, 0xCF, 0x0C, 0xD3,
69      0x68}};  // Production
70 
71 static uint8_t ApduPutKeyUser1[UK_NB][50] = {
72     {0x2F, 0x04, 0x2F, 0x84, 0x11, 0x00, 0x00, 0x2A, 0x01, 0xB3,
73      0x56, 0x01,  // Test
74      0x00, 0x00, 0xFD, 0x20, 0x20, 0xEC, 0x7D, 0x47, 0xAE, 0xF3,
75      0x23, 0x2E, 0x00, 0x00, 0x34, 0x78, 0x82, 0xEC, 0x6b, 0xA5,
76      0x83, 0xAF, 0x68, 0xC7, 0x1F, 0x9F, 0xB0, 0xD7, 0x9D, 0x33,
77      0xB0, 0xDA, 0xC6, 0x2C, 0xAB, 0x8A, 0x10, 0xEA},
78     {0x2F, 0x04, 0x2F, 0x84, 0x11, 0x00, 0x00, 0x2A, 0x01, 0xB3,
79      0x56, 0x01,  // Production
80      0x00, 0x00, 0xFD, 0x20, 0x20, 0xEC, 0x7D, 0x47, 0xAE, 0xF3,
81      0x23, 0x2E, 0x00, 0x00, 0xE1, 0xA2, 0x78, 0xA9, 0x71, 0x14,
82      0x46, 0x6D, 0x73, 0x86, 0x4C, 0x3B, 0x0F, 0x51, 0x71, 0x8E,
83      0xE4, 0x1D, 0x54, 0x02, 0x3A, 0xE3, 0x18, 0x55}};
84 
85 static uint8_t ApduEraseUpgradeStart[] = {
86     0x2F, 0x04, 0x12, 0x84, 0x35, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
87     0x00, 0x01, 0xB2, 0x51, 0x42, 0xB0, 0x27, 0x92, 0xAA, 0xAB};
88 
89 static uint8_t ApduEraseNfcArea[] = {0x2F, 0x04, 0x17, 0x84, 0x36, 0x00, 0x00,
90                                      0x12, 0x00, 0x01, 0x00, 0x80, 0x00, 0x00,
91                                      0x00, 0x04, 0x5E, 0x00, 0x4D, 0x83, 0xE1,
92                                      0x59, 0x62, 0xDC, 0x14, 0x64};
93 
94 static uint8_t ApduEraseUpgradeStop[] = {0x2F, 0x04, 0x0F, 0x80, 0x33, 0x00,
95                                          0x00, 0x0A, 0x00, 0x02, 0x97, 0x22,
96                                          0xC2, 0x5A, 0x2D, 0xA4, 0x09, 0x1A};
97 
98 static uint8_t ApduSetVariousConfig[] = {
99     0x2F, 0x04, 0x11, 0x84, 0x74, 0x00, 0x00, 0x0C, 0x06, 0x02,
100     0x80, 0x80, 0xD4, 0x29, 0xEC, 0x9A, 0xFB, 0xC8, 0x4B, 0x2A};
101 
102 static uint8_t ApduSwitchToUser[] = {0x2F, 0x04, 0x0F, 0x84, 0xA0, 0x00,
103                                      0x00, 0x0A, 0x20, 0x01, 0xFC, 0x63,
104                                      0x2A, 0xE1, 0xFD, 0xAA, 0xD1, 0x9B};
105 
106 static const uint8_t nciHeaderPropSetUwbConfig[9] = {
107     0x2F, 0x02, 0x00, 0x04, 0x00, 0x16, 0x01, 0x00, 0x00};
108 static const uint8_t nciGetPropConfig[8] = {0x2F, 0x02, 0x05, 0x03,
109                                             0x00, 0x06, 0x01, 0x00};
110 static const uint8_t nciSetPropConfig[9] = {0x2F, 0x02, 0x00, 0x04, 0x00,
111                                             0x06, 0x01, 0x00, 0x00};
112 static uint8_t nciPropSetUwbConfig[128];
113 static uint8_t nciPropSetConfig_CustomField[64];
114 hal_fd_state_e mHalFDState = HAL_FD_STATE_AUTHENTICATE;
115 hal_fd_st54l_state_e mHalFD54LState = HAL_FD_ST54L_STATE_PUY_KEYUSER;
116 void SendExitLoadMode(HALHANDLE mmHalHandle);
117 void SendSwitchToUserMode(HALHANDLE mmHalHandle);
118 extern void hal_wrapper_update_complete();
119 
120 typedef size_t (*STLoadUwbParams)(void *out_buff,
121                                   size_t buf_size);
122 
123 /***********************************************************************
124  * Determine UserKey
125  *
126  * @return mode: -1 : not supported
127  *                0 : Test sample
128  *                1 : Product sample
129  ***********************************************************************/
GetProdType(uint8_t * UserKey)130 static int GetProdType(uint8_t* UserKey) {
131   int i, j;
132   int status;
133 
134   for (i = 0; i < UK_NB; i++) {
135     status = 1;
136     for (j = 0; j < UK_SIZE; j++) {
137       if (UserKey[j] != UserKeys[i][j]) {
138         STLOG_HAL_D(
139             "   No match between UserKey[%d]=0x%02X and \
140                 UserKeys[%d][%d]=0x%02X",
141             j, UserKey[j], i, j, UserKeys[i][j]);
142         status = 0;
143         break;
144       }
145     }
146     if (1 == status) {
147       return i;
148     }
149   }
150   return (-1);
151 }
152 
153 /**
154  * Send a HW reset and decode NCI_CORE_RESET_NTF information
155  * @param pHwVersion is used to return HW version, part of NCI_CORE_RESET_NTF
156  * @param pFwVersion is used to return FW version, part of NCI_CORE_RESET_NTF
157  * @param pLoaderVersion is used to return Loader version, part of
158  * NCI_CORE_RESET_NTF
159  * @param pCustVersion si used to return Customer field value, part of
160  * NCI_CORE_RESET_NTF when in router mode
161  *
162  * @return mode: FT_CLF_MODE_ROUTER if router mode
163  *               FT_CLF_MODE_LOADER if loader mode
164  *               FT_CLF_MODE_ERROR if Error
165  */
166 
hal_fd_init()167 int hal_fd_init() {
168   uint8_t result = 0;
169   char FwPath[256];
170   char ConfPath[256];
171   char fwBinName[256];
172   char fwConfName[256];
173   int ret;
174 
175   STLOG_HAL_D("  %s - enter", __func__);
176 
177   if (!GetStrValue(NAME_STNFC_FW_PATH_STORAGE, (char *)FwPath,
178                    sizeof(FwPath))) {
179     STLOG_HAL_D(
180         "%s - FW path not found in conf. use default location /vendor/firmware "
181         "\n", __func__);
182     strcpy(FwPath, "/vendor/firmware");
183   }
184 
185   if (!GetStrValue(NAME_STNFC_FW_BIN_NAME, (char *)fwBinName,
186                    sizeof(fwBinName))) {
187     STLOG_HAL_D(
188         "%s - FW binary file name not found in conf. use default name "
189         "/st21nfc_fw.bin \n", __func__);
190     strcpy(fwBinName, "/st21nfc_fw.bin");
191   }
192 
193   if (!GetStrValue(NAME_STNFC_FW_CONF_NAME, (char *)fwConfName,
194                    sizeof(fwConfName))) {
195     STLOG_HAL_D(
196         "%s - FW config file name not found in conf. use default name "
197         "/st21nfc_conf.bin \n", __func__);
198     strcpy(fwConfName, "/st21nfc_conf.bin");
199   }
200 
201   // Getting information about FW patch, if any
202   strcpy(ConfPath, FwPath);
203   strncat(FwPath, fwBinName, sizeof(FwPath) - strlen(FwPath) - 1);
204   strncat(ConfPath, fwConfName, sizeof(ConfPath) - strlen(ConfPath) - 1);
205   STLOG_HAL_D("%s - FW update binary file = %s", __func__, FwPath);
206   STLOG_HAL_D("%s - FW config binary file = %s", __func__, ConfPath);
207 
208   // Initializing structure holding FW patch details
209   mFWInfo = (FWInfo *)malloc(sizeof(FWInfo));
210 
211   if (mFWInfo == NULL) {
212     result = 0;
213   }
214 
215   memset(mFWInfo, 0, sizeof(FWInfo));
216 
217   // Initializing structure holding FW Capabilities
218   mFWCap = (FWCap *)malloc(sizeof(FWCap));
219 
220   if (mFWCap == NULL) {
221     result = 0;
222   }
223 
224   memset(mFWCap, 0, sizeof(FWCap));
225 
226   mFwFileBin = NULL;
227   mCustomFileBin = NULL;
228 
229   // Check if FW patch binary file is present
230   // If not, get recovery FW patch file
231   if ((mFwFileBin = fopen((char *)FwPath, "r")) == NULL) {
232     STLOG_HAL_D("%s - %s not detected", __func__, fwBinName);
233   } else {
234     STLOG_HAL_D("%s - %s file detected\n", __func__, fwBinName);
235     result |= FW_PATCH_AVAILABLE;
236 
237     ret = fread(mBinData, sizeof(uint8_t), 4, mFwFileBin);
238     if (ret != 4) {
239       STLOG_HAL_E("%s did not read 4 bytes \n", __func__);
240     }
241     mFWInfo->fileFwVersion =
242         mBinData[0] << 24 | mBinData[1] << 16 | mBinData[2] << 8 | mBinData[3];
243 
244     fgetpos(mFwFileBin, &mPosInit);
245     ret = fread(mBinData, sizeof(uint8_t), 5, mFwFileBin);
246     if (ret != 5) {
247       STLOG_HAL_E("%s did not read 5 bytes \n", __func__);
248     }
249     fsetpos(mFwFileBin, &mPosInit);  // reset pos in stream
250 
251     if (mBinData[4] == 0x35) {
252       mFWInfo->fileHwVersion = HW_ST54L;
253     } else {
254       ret = fread(mApduAuthent, sizeof(uint8_t), 24, mFwFileBin);
255       if (ret != 24) {
256         STLOG_HAL_E("%s Wrong read nb \n", __func__);
257       }
258 
259       // We use the last byte of the auth command to discriminate at the moment.
260       // it can be extended in case of conflict later.
261       switch (mApduAuthent[23]) {
262         case 0x43:
263         case 0xC7:
264           mFWInfo->fileHwVersion = HW_NFCD;
265           break;
266 
267         case 0xE9:
268           mFWInfo->fileHwVersion = HW_ST54J;
269           break;
270       }
271     }
272 
273     if (mFWInfo->fileHwVersion == 0) {
274       STLOG_HAL_E("%s --> %s integrates unknown patch NFC FW -- rejected\n",
275                   __func__, FwPath);
276       fclose(mFwFileBin);
277       mFwFileBin = NULL;
278     } else {
279       fgetpos(mFwFileBin, &mPosInit);
280 
281       STLOG_HAL_D("%s --> %s integrates patch NFC FW version 0x%08X (r:%d)\n",
282                   __func__, FwPath, mFWInfo->fileFwVersion,
283                   mFWInfo->fileHwVersion);
284     }
285   }
286 
287   if ((mCustomFileBin = fopen((char *)ConfPath, "r")) == NULL) {
288     STLOG_HAL_D("%s - st21nfc custom configuration not detected\n", __func__);
289   } else {
290     STLOG_HAL_D("%s - %s file detected\n", __func__, ConfPath);
291     fread(mBinData, sizeof(uint8_t), 2, mCustomFileBin);
292     mFWInfo->fileCustVersion = mBinData[0] << 8 | mBinData[1];
293     STLOG_HAL_D("%s --> st21nfc_custom configuration version 0x%04X \n",
294                 __func__, mFWInfo->fileCustVersion);
295     result |= FW_CUSTOM_PARAM_AVAILABLE;
296   }
297 
298   if (ft_CheckUWBConf()) {
299     result |= FW_UWB_PARAM_AVAILABLE;
300   }
301 
302   return result;
303 }
304 
hal_fd_close()305 void hal_fd_close() {
306   STLOG_HAL_D("  %s -enter", __func__);
307   mCustomParamFailed = false;
308   if (mFWInfo != NULL) {
309     free(mFWInfo);
310     mFWInfo = NULL;
311   }
312   if (mFwFileBin != NULL) {
313     fclose(mFwFileBin);
314     mFwFileBin = NULL;
315   }
316   if (mCustomFileBin != NULL) {
317     fclose(mCustomFileBin);
318     mCustomFileBin = NULL;
319   }
320 }
321 
hal_fd_getFwInfo()322 FWInfo* hal_fd_getFwInfo() {
323   STLOG_HAL_D("  %s -enter", __func__);
324    return mFWInfo;
325 }
326 
hal_fd_getFwCap()327 FWCap* hal_fd_getFwCap() {
328   STLOG_HAL_D("  %s -enter", __func__);
329    return mFWCap;
330 }
331 
332 /**
333  * Send a HW reset and decode NCI_CORE_RESET_NTF information
334  * @param pHwVersion is used to return HW version, part of NCI_CORE_RESET_NTF
335  * @param pFwVersion is used to return FW version, part of NCI_CORE_RESET_NTF
336  * @param pLoaderVersion is used to return Loader version, part of
337  * NCI_CORE_RESET_NTF
338  * @param pCustVersion si used to return Customer field value, part of
339  * NCI_CORE_RESET_NTF when in router mode
340  *
341  * @return mode: FT_CLF_MODE_ROUTER if router mode
342  *               FT_CLF_MODE_LOADER if loader mode
343  *               FT_CLF_MODE_ERROR if Error
344  */
345 
ft_cmd_HwReset(uint8_t * pdata,uint8_t * clf_mode)346 uint8_t ft_cmd_HwReset(uint8_t *pdata, uint8_t *clf_mode) {
347   uint8_t result = 0;
348 
349   STLOG_HAL_D("  %s - execution", __func__);
350 
351   if ((pdata[1] == 0x0) && (pdata[3] == 0x1)) {
352     STLOG_HAL_D("-> Router Mode NCI_CORE_RESET_NTF received after HW Reset");
353 
354     /* retrieve HW Version from NCI_CORE_RESET_NTF */
355     mFWInfo->chipHwVersion = pdata[8];
356     STLOG_HAL_D("   HwVersion = 0x%02X", mFWInfo->chipHwVersion);
357 
358     /* retrieve FW Version from NCI_CORE_RESET_NTF */
359     mFWInfo->chipFwVersion =
360         (pdata[10] << 24) | (pdata[11] << 16) | (pdata[12] << 8) | pdata[13];
361     STLOG_HAL_D("   FwVersion = 0x%08X", mFWInfo->chipFwVersion);
362     uint8_t FWVersionMajor = (uint8_t)(hal_fd_getFwInfo()->chipFwVersion >> 24);
363     uint8_t FWVersionMinor =
364         (uint8_t)((hal_fd_getFwInfo()->chipFwVersion & 0x00FF0000) >> 16);
365     /* retrieve Loader Version from NCI_CORE_RESET_NTF */
366     mFWInfo->chipLoaderVersion =
367         (pdata[14] << 16) | (pdata[15] << 8) | pdata[16];
368     STLOG_HAL_D("   LoaderVersion = 0x%06X", mFWInfo->chipLoaderVersion);
369 
370     /* retrieve Customer Version from NCI_CORE_RESET_NTF */
371     mFWInfo->chipCustVersion = (pdata[31] << 8) | pdata[32];
372     STLOG_HAL_D("   CustomerVersion = 0x%04X", mFWInfo->chipCustVersion);
373 
374     /* retrieve Uwb param Version from NCI_CORE_RESET_NTF */
375     mFWInfo->chipUwbVersion = (pdata[29] << 8) | pdata[30];
376     STLOG_HAL_D("   uwbVersion = 0x%04X", mFWInfo->chipUwbVersion);
377 
378     *clf_mode = FT_CLF_MODE_ROUTER;
379   } else if ((pdata[2] == 0x39) && (pdata[3] == 0xA1)) {
380     STLOG_HAL_D("-> Loader Mode NCI_CORE_RESET_NTF received after HW Reset");
381 
382     /* deduce HW Version from Factory Loader version */
383     if (pdata[16] == 0x01) {
384       mFWInfo->chipHwVersion = 0x05;  // ST54J
385     } else if (pdata[16] == 0x02) {
386       mFWInfo->chipHwVersion = 0x04;  // ST21NFCD
387     } else {
388       mFWInfo->chipHwVersion = 0x03;  // ST21NFCD
389     }
390     STLOG_HAL_D("   HwVersion = 0x%02X", mFWInfo->chipHwVersion);
391 
392     /* Identify the Active loader. Normally only one should be detected*/
393     if (pdata[11] == 0xA0) {
394       mFWInfo->chipLoaderVersion =
395           (pdata[8] << 16) | (pdata[9] << 8) | pdata[10];
396       STLOG_HAL_D("         - Most recent loader activated, revision 0x%06X",
397                   mFWInfo->chipLoaderVersion);
398     }
399     if (pdata[15] == 0xA0) {
400       mFWInfo->chipLoaderVersion =
401           (pdata[12] << 16) | (pdata[13] << 8) | pdata[14];
402       STLOG_HAL_D("         - Least recent loader activated, revision 0x%06X",
403                   mFWInfo->chipLoaderVersion);
404     }
405     if (pdata[19] == 0xA0) {
406       mFWInfo->chipLoaderVersion =
407           (pdata[16] << 16) | (pdata[17] << 8) | pdata[18];
408       STLOG_HAL_D("         - Factory loader activated, revision 0x%06X",
409                   mFWInfo->chipLoaderVersion);
410     }
411 
412     *clf_mode = FT_CLF_MODE_LOADER;
413   } else if ((pdata[2] == 0x41) && (pdata[3] == 0xA2)) {
414     STLOG_HAL_D("-> Loader V3 Mode NCI_CORE_RESET_NTF received after HW Reset");
415     mFWInfo->chipHwVersion = HW_ST54L;
416     STLOG_HAL_D("   HwVersion = 0x%02X", mFWInfo->chipHwVersion);
417     mFWInfo->chipFwVersion = 0;  // make sure FW will be updated.
418     /* retrieve Production type* from NCI_CORE_RESET_NTF */
419     mFWInfo->chipProdType = GetProdType(&pdata[44]);
420     *clf_mode = FT_CLF_MODE_LOADER;
421   } else {
422     STLOG_HAL_E(
423         "%s --> ERROR: wrong NCI_CORE_RESET_NTF received after HW Reset",
424         __func__);
425     *clf_mode = FT_CLF_MODE_ERROR;
426   }
427 
428   if ((mFWInfo->chipHwVersion == HW_ST54J) ||
429       (mFWInfo->chipHwVersion == HW_ST54L)) {
430     if ((mFwFileBin != NULL) &&
431         (mFWInfo->fileFwVersion != mFWInfo->chipFwVersion)) {
432       STLOG_HAL_D("---> Firmware update needed\n");
433       result |= FW_UPDATE_NEEDED;
434     } else {
435       STLOG_HAL_D("---> No Firmware update needed\n");
436     }
437 
438     if ((mFWInfo->fileCustVersion != 0) &&
439         (mFWInfo->chipCustVersion != mFWInfo->fileCustVersion)) {
440       STLOG_HAL_D(
441           "%s - Need to apply new st21nfc custom configuration settings\n",
442           __func__);
443       if (!mCustomParamFailed) result |= CONF_UPDATE_NEEDED;
444     } else {
445       STLOG_HAL_D("%s - No need to apply custom configuration settings\n",
446                   __func__);
447     }
448   }
449   if ((mFWInfo->fileUwbVersion != 0) &&
450       (mFWInfo->fileUwbVersion != mFWInfo->chipUwbVersion)) {
451     result |= UWB_CONF_UPDATE_NEEDED;
452     STLOG_HAL_D("%s - Need to apply new uwb param configuration \n", __func__);
453     mUwbConfigNeeded = true;
454   }
455 
456   uint8_t FWVersionMajor = (uint8_t)(hal_fd_getFwInfo()->chipFwVersion >> 24);
457   uint8_t FWVersionMinor =
458         (uint8_t)((hal_fd_getFwInfo()->chipFwVersion & 0x00FF0000) >> 16);
459 
460   if (hal_fd_getFwInfo()->chipHwVersion == HW_ST54L &&
461       (FWVersionMajor >= 0x2) && (FWVersionMinor >= 0x5)) {
462     mFWCap->ObserveMode = 0x2;
463   } else {
464     mFWCap->ObserveMode = 0x1;
465   }
466   return result;
467 } /* ft_cmd_HwReset */
468 
ExitHibernateHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)469 void ExitHibernateHandler(HALHANDLE mHalHandle, uint16_t data_len,
470                           uint8_t *p_data) {
471   STLOG_HAL_D("%s - Enter", __func__);
472   if (data_len < 3) {
473     STLOG_HAL_E("%s - Error, too short data (%d)", __func__, data_len);
474     return;
475   }
476   switch (p_data[0]) {
477     case 0x40:  //
478       STLOG_HAL_D("%s - hibernate_exited = %d ", __func__,
479                   mFWInfo->hibernate_exited);
480 
481       // CORE_INIT_RSP
482       if ((p_data[1] == 0x1) && (p_data[3] == 0x0) &&
483           (mFWInfo->hibernate_exited == 0)) {
484         // Send PROP_NFC_MODE_SET_CMD(ON)
485         if (!HalSendDownstream(mHalHandle, propNfcModeSetCmdOn,
486                                sizeof(propNfcModeSetCmdOn))) {
487           STLOG_HAL_E("%s - SendDownstream failed", __func__);
488         }
489       } else if ((p_data[1] == 0x1) && (p_data[3] == 0x0) &&
490                  (mFWInfo->hibernate_exited == 1)) {
491         STLOG_HAL_D(
492             "%s - send NCI_PROP_NFC_FW_UPDATE_CMD and use 100 ms timer for "
493             "each cmd from here",
494             __func__);
495 
496         if (!HalSendDownstreamTimer(mHalHandle, NciPropNfcFwUpdate,
497                                     sizeof(NciPropNfcFwUpdate),
498                                     FW_TIMER_DURATION)) {
499           STLOG_HAL_E("%s  SendDownstream failed", __func__);
500         }
501       } else if (p_data[3] != 0x00) {
502         STLOG_HAL_D("%s - Wrong response. Retry HW reset", __func__);
503         I2cResetPulse();
504         hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
505       }
506       break;
507 
508     case 0x4f:  //
509       if ((p_data[1] == 0x02) && (p_data[3] == 0x00) &&
510           (mFWInfo->hibernate_exited == 1)) {
511         STLOG_HAL_D("%s - NCI_PROP_NFC_FW_RSP : loader mode", __func__);
512         I2cResetPulse();
513         hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
514       } else if (p_data[3] != 0x00) {
515         STLOG_HAL_D("%s - Wrong response. Retry HW reset", __func__);
516         I2cResetPulse();
517         hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
518       }
519       break;
520     case 0x60:  //
521       if (p_data[3] == 0x2) {
522         STLOG_HAL_D("%s - CORE_RESET_NTF : after core_reset_cmd", __func__);
523 
524         if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
525           STLOG_HAL_E("%s - SendDownstream failed", __func__);
526         }
527       } else if (p_data[3] == 0xa0) {
528         mFWInfo->hibernate_exited = 1;
529         STLOG_HAL_D("%s - hibernate_exited = %d ", __func__,
530                     mFWInfo->hibernate_exited);
531 
532         if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
533           STLOG_HAL_E("%s - SendDownstream failed", __func__);
534         }
535       }
536       break;
537   }
538 }
539 
ft_CheckUWBConf()540 bool ft_CheckUWBConf() {
541 
542   char uwbLibName[256];
543   STLOG_HAL_D("%s", __func__);
544 
545   if (!GetStrValue(NAME_STNFC_UWB_LIB_NAME, (char *)uwbLibName,
546                    sizeof(uwbLibName))) {
547     STLOG_HAL_D(
548         "%s - UWB conf library name not found in conf. use default name ", __func__);
549     strcpy(uwbLibName, "/vendor/lib64/libqorvo_uwb_params_nfcc.so");
550   }
551 
552   STLOG_HAL_D("%s - UWB conf library = %s", __func__, uwbLibName);
553 
554   void *stdll = dlopen(uwbLibName, RTLD_NOW);
555   if (stdll) {
556     STLoadUwbParams fn =
557         (STLoadUwbParams)dlsym(stdll, "load_uwb_params_from_files");
558   if (fn) {
559     size_t lengthOutput =
560         fn(nciPropSetUwbConfig + 9, 100);
561     STLOG_HAL_D("%s: lengthOutput = %zu", __func__, lengthOutput);
562     if (lengthOutput > 0) {
563       memcpy(nciPropSetUwbConfig, nciHeaderPropSetUwbConfig, 9);
564       nciPropSetUwbConfig[2] = lengthOutput + 6;
565       nciPropSetUwbConfig[8] = lengthOutput;
566       mFWInfo->fileUwbVersion =
567           nciPropSetUwbConfig[9] << 8 | nciPropSetUwbConfig[10];
568       STLOG_HAL_D("%s --> uwb configuration version 0x%04X \n", __func__,
569                   mFWInfo->fileUwbVersion);
570       return true;
571     } else {
572       STLOG_HAL_D("%s: lengthOutput null", __func__);
573     }
574    }
575   } else {
576     STLOG_HAL_D("libqorvo_uwb_params_nfcc not found, do nothing.");
577   }
578   return false;
579 }
580 /*******************************************************************************
581 **
582 ** Function         resetHandlerState
583 **
584 ** Description      Reset FW update state.
585 **
586 ** Parameters       void
587 **
588 **
589 *******************************************************************************/
resetHandlerState()590 void resetHandlerState() {
591   STLOG_HAL_D("%s", __func__);
592   mHalFDState = HAL_FD_STATE_AUTHENTICATE;
593   mHalFD54LState = HAL_FD_ST54L_STATE_PUY_KEYUSER;
594 }
595 
596 /*******************************************************************************
597 **
598 ** Function         UpdateHandler
599 **
600 ** Description      Handler to update ST54J NFCC FW.
601 **
602 ** Parameters       mHalHandle - HAL handle
603 **                  data_len   - Buffer length
604 **                  p_data     - Data buffer from NFCC
605 **
606 **
607 *******************************************************************************/
UpdateHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)608 void UpdateHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t *p_data) {
609   HalSendDownstreamStopTimer(mHalHandle);
610 
611   switch (mHalFDState) {
612     case HAL_FD_STATE_AUTHENTICATE:
613       STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_AUTHENTICATE", __func__);
614 
615       if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
616         STLOG_HAL_D("%s - send APDU_AUTHENTICATION_CMD", __func__);
617         if (!HalSendDownstreamTimer(mHalHandle, (uint8_t *)mApduAuthent,
618                                     sizeof(mApduAuthent), FW_TIMER_DURATION)) {
619           STLOG_HAL_E("%s - SendDownstream failed", __func__);
620         }
621         mHalFDState = HAL_FD_STATE_ERASE_FLASH;
622       } else {
623         STLOG_HAL_D("%s - FW flash not succeeded", __func__);
624         SendExitLoadMode(mHalHandle);
625       }
626       break;
627 
628     case HAL_FD_STATE_ERASE_FLASH:  // 1
629       STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_ERASE_FLASH", __func__);
630 
631       if ((p_data[0] == 0x4f) && (p_data[1] == 0x04)) {
632         if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
633           STLOG_HAL_D(
634               " %s - send APDU_ERASE_FLASH_CMD (keep appli and NDEF areas)",
635               __func__);
636 
637           if (!HalSendDownstreamTimer(mHalHandle, ApduEraseNfcKeepAppliAndNdef,
638                                       sizeof(ApduEraseNfcKeepAppliAndNdef),
639                                       FW_TIMER_DURATION)) {
640             STLOG_HAL_E("%s - SendDownstream failed", __func__);
641           }
642 
643           fsetpos(mFwFileBin, &mPosInit);  // reset pos in stream
644 
645           mHalFDState = HAL_FD_STATE_SEND_RAW_APDU;
646 
647         } else {
648           STLOG_HAL_D("%s - FW flash not succeeded", __func__);
649           SendExitLoadMode(mHalHandle);
650         }
651       }
652       break;
653 
654     case HAL_FD_STATE_SEND_RAW_APDU:  // 3
655       STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_SEND_RAW_APDU", __func__);
656       if ((p_data[0] == 0x4f) && (p_data[1] == 0x04)) {
657         if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
658           mRetry = true;
659 
660           fgetpos(mFwFileBin, &mPos);  // save current position in stream
661           if ((fread(mBinData, sizeof(uint8_t), 3, mFwFileBin) == 3) &&
662               (fread(mBinData + 3, sizeof(uint8_t), mBinData[2], mFwFileBin) ==
663                mBinData[2])) {
664             if (!HalSendDownstreamTimer(mHalHandle, mBinData, mBinData[2] + 3,
665                                         FW_TIMER_DURATION)) {
666               STLOG_HAL_E("%s - SendDownstream failed", __func__);
667             }
668           } else {
669             STLOG_HAL_D("%s - EOF of FW binary", __func__);
670             SendExitLoadMode(mHalHandle);
671           }
672         } else if (mRetry == true) {
673           STLOG_HAL_D("%s - Last Tx was NOK. Retry", __func__);
674           mRetry = false;
675           fsetpos(mFwFileBin, &mPos);
676           if ((fread(mBinData, sizeof(uint8_t), 3, mFwFileBin) == 3) &&
677               (fread(mBinData + 3, sizeof(uint8_t), mBinData[2], mFwFileBin) ==
678                mBinData[2])) {
679             if (!HalSendDownstreamTimer(mHalHandle, mBinData, mBinData[2] + 3,
680                                         FW_TIMER_DURATION)) {
681               STLOG_HAL_E("%s - SendDownstream failed", __func__);
682             }
683             fgetpos(mFwFileBin, &mPos);  // save current position in stream
684           } else {
685             STLOG_HAL_D("%s - EOF of FW binary", __func__);
686             SendExitLoadMode(mHalHandle);
687           }
688         } else {
689           STLOG_HAL_D("%s - FW flash not succeeded.", __func__);
690           I2cResetPulse();
691           SendExitLoadMode(mHalHandle);
692         }
693       }
694       break;
695 
696     case HAL_FD_STATE_EXIT_APDU:  // 2
697       STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_EXIT_APDU", __func__);
698       if ((p_data[data_len - 2] != 0x90) || (p_data[data_len - 1] != 0x00)) {
699         STLOG_HAL_D(
700             "%s - Error exiting loader mode, i.e. a problem occurred"
701             "during FW update",
702             __func__);
703       }
704 
705       I2cResetPulse();
706       hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
707       mHalFDState = HAL_FD_STATE_AUTHENTICATE;
708       break;
709 
710     default:
711       STLOG_HAL_D("%s - mHalFDState = unknown", __func__);
712       STLOG_HAL_D("%s - FW flash not succeeded", __func__);
713       SendExitLoadMode(mHalHandle);
714       break;
715   }
716 }
717 
718 /*******************************************************************************
719 **
720 ** Function         UpdateHandlerST54L
721 **
722 ** Description      Handler to update ST54L NFCC FW.
723 **
724 ** Parameters       mHalHandle - HAL handle
725 **                  data_len   - Buffer length
726 **                  p_data     - Data buffer from NFCC
727 **
728 **
729 *******************************************************************************/
UpdateHandlerST54L(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)730 static void UpdateHandlerST54L(HALHANDLE mHalHandle, uint16_t data_len,
731                                uint8_t* p_data) {
732   STLOG_HAL_D("%s : Enter state = %d", __func__, mHalFD54LState);
733 
734   switch (mHalFD54LState) {
735     case HAL_FD_ST54L_STATE_PUY_KEYUSER:
736       if (!HalSendDownstreamTimer(
737               mHalHandle, (uint8_t*)ApduPutKeyUser1[mFWInfo->chipProdType],
738               sizeof(ApduPutKeyUser1[mFWInfo->chipProdType]),
739               FW_TIMER_DURATION)) {
740         STLOG_HAL_E("%s - SendDownstream failed", __func__);
741       }
742       mHalFD54LState = HAL_FD_ST54L_STATE_ERASE_UPGRADE_START;
743       break;
744 
745     case HAL_FD_ST54L_STATE_ERASE_UPGRADE_START:
746       if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
747         if (!HalSendDownstreamTimer(mHalHandle, (uint8_t*)ApduEraseUpgradeStart,
748                                     sizeof(ApduEraseUpgradeStart),
749                                     FW_TIMER_DURATION)) {
750           STLOG_HAL_E("%s - SendDownstream failed", __func__);
751         }
752         mHalFD54LState = HAL_FD_ST54L_STATE_ERASE_NFC_AREA;
753       } else {
754         STLOG_HAL_D("%s - FW flash not succeeded", __func__);
755         SendSwitchToUserMode(mHalHandle);
756       }
757       break;
758 
759     case HAL_FD_ST54L_STATE_ERASE_NFC_AREA:
760       if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
761         if (!HalSendDownstreamTimer(mHalHandle, (uint8_t*)ApduEraseNfcArea,
762                                     sizeof(ApduEraseNfcArea),
763                                     FW_TIMER_DURATION)) {
764           STLOG_HAL_E("%s - SendDownstream failed", __func__);
765         }
766         mHalFD54LState = HAL_FD_ST54L_STATE_ERASE_UPGRADE_STOP;
767       } else {
768         STLOG_HAL_D("%s - FW flash not succeeded", __func__);
769         SendSwitchToUserMode(mHalHandle);
770       }
771       break;
772 
773     case HAL_FD_ST54L_STATE_ERASE_UPGRADE_STOP:
774       if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
775         if (!HalSendDownstreamTimer(mHalHandle, (uint8_t*)ApduEraseUpgradeStop,
776                                     sizeof(ApduEraseUpgradeStop),
777                                     FW_TIMER_DURATION)) {
778           STLOG_HAL_E("%s - SendDownstream failed", __func__);
779         }
780         mHalFD54LState = HAL_FD_ST54L_STATE_SEND_RAW_APDU;
781       } else {
782         STLOG_HAL_D("%s - FW flash not succeeded", __func__);
783         SendSwitchToUserMode(mHalHandle);
784       }
785       break;
786 
787     case HAL_FD_ST54L_STATE_SEND_RAW_APDU:
788       STLOG_HAL_D("%s - mHalFDState = HAL_FD_ST54L_STATE_SEND_RAW_APDU",
789                   __func__);
790       if ((p_data[0] == 0x4f) && (p_data[1] == 0x04)) {
791         if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
792           mRetry = true;
793 
794           fgetpos(mFwFileBin, &mPos);  // save current position in stream
795           if ((fread(mBinData, sizeof(uint8_t), 3, mFwFileBin) == 3) &&
796               (fread(mBinData + 3, sizeof(uint8_t), mBinData[2], mFwFileBin) ==
797                mBinData[2])) {
798             if (!HalSendDownstreamTimer(mHalHandle, mBinData, mBinData[2] + 3,
799                                         FW_TIMER_DURATION)) {
800               STLOG_HAL_E("%s - SendDownstream failed", __func__);
801             }
802           } else {
803             STLOG_HAL_D("%s - EOF of FW binary", __func__);
804             if (!HalSendDownstreamTimer(
805                     mHalHandle, (uint8_t*)ApduSetVariousConfig,
806                     sizeof(ApduSetVariousConfig), FW_TIMER_DURATION)) {
807               STLOG_HAL_E("%s - SendDownstream failed", __func__);
808             }
809             mHalFD54LState = HAL_FD_ST54L_STATE_SET_CONFIG;
810           }
811         } else if (mRetry == true) {
812           STLOG_HAL_D("%s - Last Tx was NOK. Retry", __func__);
813           mRetry = false;
814           fsetpos(mFwFileBin, &mPos);
815           if ((fread(mBinData, sizeof(uint8_t), 3, mFwFileBin) == 3) &&
816               (fread(mBinData + 3, sizeof(uint8_t), mBinData[2], mFwFileBin) ==
817                mBinData[2])) {
818             if (!HalSendDownstreamTimer(mHalHandle, mBinData, mBinData[2] + 3,
819                                         FW_TIMER_DURATION)) {
820               STLOG_HAL_E("%s - SendDownstream failed", __func__);
821             }
822             fgetpos(mFwFileBin, &mPos);  // save current position in stream
823           } else {
824             STLOG_HAL_D("%s - EOF of FW binary", __func__);
825             if (!HalSendDownstreamTimer(
826                     mHalHandle, (uint8_t*)ApduSetVariousConfig,
827                     sizeof(ApduSetVariousConfig), FW_TIMER_DURATION)) {
828               STLOG_HAL_E("%s - SendDownstream failed", __func__);
829             }
830             mHalFD54LState = HAL_FD_ST54L_STATE_SET_CONFIG;
831           }
832         } else {
833           STLOG_HAL_D("%s - FW flash not succeeded.", __func__);
834           I2cResetPulse();
835           SendSwitchToUserMode(mHalHandle);
836         }
837       }
838       break;
839 
840     case HAL_FD_ST54L_STATE_SET_CONFIG:
841 
842       if ((p_data[0] == 0x4f) && (p_data[1] == 0x04)) {
843         SendSwitchToUserMode(mHalHandle);
844       }
845       break;
846 
847     case HAL_FD_ST54L_STATE_SWITCH_TO_USER:
848       if ((p_data[data_len - 2] != 0x90) || (p_data[data_len - 1] != 0x00)) {
849         STLOG_HAL_D(
850             "%s - Error exiting loader mode, i.e. a problem occurred during FW "
851             "update",
852             __func__);
853       }
854 
855       I2cResetPulse();
856       hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
857       mHalFD54LState = HAL_FD_ST54L_STATE_PUY_KEYUSER;
858       break;
859 
860     default:
861       STLOG_HAL_D("%s - mHalFD54LState = unknown", __func__);
862       STLOG_HAL_D("%s - FW flash not succeeded", __func__);
863       SendSwitchToUserMode(mHalHandle);
864       break;
865   }
866 }
867 
868 /*******************************************************************************
869 **
870 ** Function         FwUpdateHandler
871 **
872 ** Description      Handler to update NFCC FW.
873 **
874 ** Parameters       mHalHandle - HAL handle
875 **                  data_len   - Buffer length
876 **                  p_data     - Data buffer from NFCC
877 **
878 **
879 *******************************************************************************/
FwUpdateHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)880 void FwUpdateHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t* p_data) {
881   if (mFWInfo->chipHwVersion == HW_ST54L) {
882     UpdateHandlerST54L(mHalHandle, data_len, p_data);
883   } else {
884     UpdateHandler(mHalHandle, data_len, p_data);
885   }
886 }
887 
ApplyCustomParamHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)888 void ApplyCustomParamHandler(HALHANDLE mHalHandle, uint16_t data_len,
889                              uint8_t *p_data) {
890   STLOG_HAL_D("%s - Enter ", __func__);
891   if (data_len < 3) {
892     STLOG_HAL_E("%s : Error, too short data (%d)", __func__, data_len);
893     return;
894   }
895 
896   switch (p_data[0]) {
897     case 0x40:  //
898       // CORE_RESET_RSP
899       if ((p_data[1] == 0x0) && (p_data[3] == 0x0)) {
900         // do nothing
901       } else if ((p_data[1] == 0x1) && (p_data[3] == 0x0)) {
902         if (mFWInfo->hibernate_exited == 0) {
903           // Send a NFC mode on .
904           if (!HalSendDownstream(mHalHandle, propNfcModeSetCmdOn,
905                                  sizeof(propNfcModeSetCmdOn))) {
906             STLOG_HAL_E("%s - SendDownstream failed", __func__);
907           }
908           // CORE_INIT_RSP
909         } else if (mFWInfo->hibernate_exited == 1) {
910           if ((fread(mBinData, sizeof(uint8_t), 3, mCustomFileBin)) &&
911               (fread(mBinData + 3, sizeof(uint8_t), mBinData[2],
912                      mCustomFileBin))) {
913             if (!HalSendDownstream(mHalHandle, mBinData, mBinData[2] + 3)) {
914               STLOG_HAL_E("%s - SendDownstream failed", __func__);
915             }
916           }
917         }
918 
919       } else {
920         STLOG_HAL_D("%s - Error in custom param application", __func__);
921         mCustomParamFailed = true;
922         I2cResetPulse();
923         hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
924       }
925       break;
926 
927     case 0x4f:
928       if (mFWInfo->hibernate_exited == 1) {
929         if ((fread(mBinData, sizeof(uint8_t), 3, mCustomFileBin) == 3) &&
930             (fread(mBinData + 3, sizeof(uint8_t), mBinData[2],
931                    mCustomFileBin) == mBinData[2])) {
932           if (!HalSendDownstream(mHalHandle, mBinData, mBinData[2] + 3)) {
933             STLOG_HAL_E("%s - SendDownstream failed", __func__);
934           }
935         } else {
936           STLOG_HAL_D("%s - mCustomParamDone = %d", __func__, mCustomParamDone);
937           if (!mGetCustomerField) {
938             mGetCustomerField = true;
939             if (!HalSendDownstream(mHalHandle, nciGetPropConfig,
940                                    sizeof(nciGetPropConfig))) {
941               STLOG_HAL_E("%s - SendDownstream failed", __func__);
942             }
943             mGetCustomerField = true;
944 
945           } else if (!mCustomParamDone) {
946 
947             STLOG_HAL_D("%s - EOF of custom file.", __func__);
948             memset(nciPropSetConfig_CustomField, 0x0,
949                    sizeof(nciPropSetConfig_CustomField));
950             memcpy(nciPropSetConfig_CustomField, nciSetPropConfig, 9);
951             nciPropSetConfig_CustomField[8] = p_data[6];
952             nciPropSetConfig_CustomField[2] = p_data[6] + 6;
953             memcpy(nciPropSetConfig_CustomField + 9, p_data + 7, p_data[6]);
954             nciPropSetConfig_CustomField[13] = mFWInfo->chipUwbVersion >> 8;
955             nciPropSetConfig_CustomField[14] = mFWInfo->chipUwbVersion;
956 
957             if (!HalSendDownstream(mHalHandle, nciPropSetConfig_CustomField,
958                                    nciPropSetConfig_CustomField[2] + 3)) {
959               STLOG_HAL_E("%s - SendDownstream failed", __func__);
960             }
961 
962             mCustomParamDone = true;
963 
964           } else {
965             I2cResetPulse();
966             if (mUwbConfigNeeded) {
967               mCustomParamDone = false;
968               mGetCustomerField = false;
969               hal_wrapper_set_state(HAL_WRAPPER_STATE_APPLY_UWB_PARAM);
970             }
971           }
972         }
973       }
974 
975       // Check if an error has occurred for PROP_SET_CONFIG_CMD
976       // Only log a warning, do not exit code
977       if (p_data[3] != 0x00) {
978         STLOG_HAL_D("%s - Error in custom file, continue anyway", __func__);
979       }
980 
981       break;
982 
983     case 0x60:  //
984       if (p_data[1] == 0x0) {
985         if (p_data[3] == 0xa0) {
986           mFWInfo->hibernate_exited = 1;
987         }
988         if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
989           STLOG_HAL_E("%s - SendDownstream failed", __func__);
990         }
991 
992       } else if ((p_data[1] == 0x6) && mCustomParamDone) {
993         mCustomParamDone = false;
994         mGetCustomerField = false;
995         hal_wrapper_update_complete();
996       }
997       break;
998   }
999 }
1000 
ApplyUwbParamHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)1001 void ApplyUwbParamHandler(HALHANDLE mHalHandle, uint16_t data_len,
1002                           uint8_t *p_data) {
1003   STLOG_HAL_D("%s - Enter ", __func__);
1004   if (data_len < 3) {
1005     STLOG_HAL_E("%s : Error, too short data (%d)", __func__, data_len);
1006     return;
1007   }
1008 
1009   switch (p_data[0]) {
1010     case 0x40:  //
1011       // CORE_RESET_RSP
1012       if ((p_data[1] == 0x0) && (p_data[3] == 0x0)) {
1013         // do nothing
1014       } else if ((p_data[1] == 0x1) && (p_data[3] == 0x0)) {
1015         if (mFWInfo->hibernate_exited == 0) {
1016           // Send a NFC mode on .
1017           if (!HalSendDownstream(mHalHandle, propNfcModeSetCmdOn,
1018                                  sizeof(propNfcModeSetCmdOn))) {
1019             STLOG_HAL_E("%s - SendDownstream failed", __func__);
1020           }
1021           // CORE_INIT_RSP
1022         } else if ((mFWInfo->hibernate_exited == 1) && !mUwbConfigDone) {
1023           if (!HalSendDownstream(mHalHandle, nciPropSetUwbConfig,
1024                                  nciPropSetUwbConfig[2] + 3)) {
1025             STLOG_HAL_E("%s - SendDownstream failed", __func__);
1026           }
1027         }
1028 
1029       } else {
1030         STLOG_HAL_D("%s - Error in uwb param application", __func__);
1031         I2cResetPulse();
1032         hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
1033       }
1034       break;
1035 
1036     case 0x4f:
1037       if (mFWInfo->hibernate_exited == 1) {
1038         if (!mUwbConfigDone) {
1039           mUwbConfigDone = true;
1040           // Check if an error has occurred for PROP_SET_CONFIG_CMD
1041           // Only log a warning, do not exit code
1042           if (p_data[3] != 0x00) {
1043             STLOG_HAL_D("%s - Error in uwb file, continue anyway", __func__);
1044           }
1045           if (!HalSendDownstream(mHalHandle, nciGetPropConfig,
1046                                  sizeof(nciGetPropConfig))) {
1047             STLOG_HAL_E("%s - SendDownstream failed", __func__);
1048           }
1049         } else if ((p_data[1] == 0x2) && (p_data[2] == 0x0c)) {
1050           memset(nciPropSetConfig_CustomField, 0x0,
1051                  sizeof(nciPropSetConfig_CustomField));
1052           memcpy(nciPropSetConfig_CustomField, nciSetPropConfig, 9);
1053           nciPropSetConfig_CustomField[8] = p_data[6];
1054           nciPropSetConfig_CustomField[2] = p_data[6] + 6;
1055           memcpy(nciPropSetConfig_CustomField + 9, p_data + 7, p_data[6]);
1056           nciPropSetConfig_CustomField[13] = mFWInfo->fileUwbVersion >> 8;
1057           nciPropSetConfig_CustomField[14] = mFWInfo->fileUwbVersion;
1058 
1059           if (!HalSendDownstream(mHalHandle, nciPropSetConfig_CustomField,
1060                                  nciPropSetConfig_CustomField[2] + 3)) {
1061             STLOG_HAL_E("%s - SendDownstream failed", __func__);
1062           }
1063 
1064         } else {
1065           I2cResetPulse();
1066         }
1067       }
1068 
1069       break;
1070 
1071     case 0x60:  //
1072       if (p_data[1] == 0x0) {
1073         if (p_data[3] == 0xa0) {
1074           mFWInfo->hibernate_exited = 1;
1075         }
1076         if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
1077           STLOG_HAL_E("%s - SendDownstream failed", __func__);
1078         }
1079 
1080       } else if ((p_data[1] == 0x6) && mUwbConfigDone) {
1081         mUwbConfigNeeded = false;
1082         mUwbConfigDone = false;
1083         hal_wrapper_update_complete();
1084       }
1085       break;
1086   }
1087 }
1088 
SendExitLoadMode(HALHANDLE mmHalHandle)1089 void SendExitLoadMode(HALHANDLE mmHalHandle) {
1090   STLOG_HAL_D("%s - Send APDU_EXIT_LOAD_MODE_CMD", __func__);
1091 
1092   if (!HalSendDownstreamTimer(mmHalHandle, ApduExitLoadMode,
1093                               sizeof(ApduExitLoadMode), FW_TIMER_DURATION)) {
1094     STLOG_HAL_E("%s - SendDownstream failed", __func__);
1095   }
1096   mHalFDState = HAL_FD_STATE_EXIT_APDU;
1097 }
1098 
SendSwitchToUserMode(HALHANDLE mmHalHandle)1099 void SendSwitchToUserMode(HALHANDLE mmHalHandle) {
1100   STLOG_HAL_D("%s: enter", __func__);
1101 
1102   if (!HalSendDownstreamTimer(mmHalHandle, ApduSwitchToUser,
1103                               sizeof(ApduSwitchToUser), FW_TIMER_DURATION)) {
1104     STLOG_HAL_E("%s - SendDownstream failed", __func__);
1105   }
1106   mHalFD54LState = HAL_FD_ST54L_STATE_SWITCH_TO_USER;
1107 }
1108