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