• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
310 /**
311  * Send a HW reset and decode NCI_CORE_RESET_NTF information
312  * @param pHwVersion is used to return HW version, part of NCI_CORE_RESET_NTF
313  * @param pFwVersion is used to return FW version, part of NCI_CORE_RESET_NTF
314  * @param pLoaderVersion is used to return Loader version, part of
315  * NCI_CORE_RESET_NTF
316  * @param pCustVersion si used to return Customer field value, part of
317  * NCI_CORE_RESET_NTF when in router mode
318  *
319  * @return mode: FT_CLF_MODE_ROUTER if router mode
320  *               FT_CLF_MODE_LOADER if loader mode
321  *               FT_CLF_MODE_ERROR if Error
322  */
323 
ft_cmd_HwReset(uint8_t * pdata,uint8_t * clf_mode)324 uint8_t ft_cmd_HwReset(uint8_t *pdata, uint8_t *clf_mode) {
325   uint8_t result = 0;
326 
327   STLOG_HAL_D("  %s - execution", __func__);
328 
329   if ((pdata[1] == 0x0) && (pdata[3] == 0x1)) {
330     STLOG_HAL_D("-> Router Mode NCI_CORE_RESET_NTF received after HW Reset");
331 
332     /* retrieve HW Version from NCI_CORE_RESET_NTF */
333     mFWInfo->chipHwVersion = pdata[8];
334     STLOG_HAL_D("   HwVersion = 0x%02X", mFWInfo->chipHwVersion);
335 
336     /* retrieve FW Version from NCI_CORE_RESET_NTF */
337     mFWInfo->chipFwVersion =
338         (pdata[10] << 24) | (pdata[11] << 16) | (pdata[12] << 8) | pdata[13];
339     STLOG_HAL_D("   FwVersion = 0x%08X", mFWInfo->chipFwVersion);
340 
341     /* retrieve Loader Version from NCI_CORE_RESET_NTF */
342     mFWInfo->chipLoaderVersion =
343         (pdata[14] << 16) | (pdata[15] << 8) | pdata[16];
344     STLOG_HAL_D("   LoaderVersion = 0x%06X", mFWInfo->chipLoaderVersion);
345 
346     /* retrieve Customer Version from NCI_CORE_RESET_NTF */
347     mFWInfo->chipCustVersion = (pdata[31] << 8) | pdata[32];
348     STLOG_HAL_D("   CustomerVersion = 0x%04X", mFWInfo->chipCustVersion);
349 
350     /* retrieve Uwb param Version from NCI_CORE_RESET_NTF */
351     mFWInfo->chipUwbVersion = (pdata[29] << 8) | pdata[30];
352     STLOG_HAL_D("   uwbVersion = 0x%04X", mFWInfo->chipUwbVersion);
353 
354     *clf_mode = FT_CLF_MODE_ROUTER;
355   } else if ((pdata[2] == 0x39) && (pdata[3] == 0xA1)) {
356     STLOG_HAL_D("-> Loader Mode NCI_CORE_RESET_NTF received after HW Reset");
357 
358     /* deduce HW Version from Factory Loader version */
359     if (pdata[16] == 0x01) {
360       mFWInfo->chipHwVersion = 0x05;  // ST54J
361     } else if (pdata[16] == 0x02) {
362       mFWInfo->chipHwVersion = 0x04;  // ST21NFCD
363     } else {
364       mFWInfo->chipHwVersion = 0x03;  // ST21NFCD
365     }
366     STLOG_HAL_D("   HwVersion = 0x%02X", mFWInfo->chipHwVersion);
367 
368     /* Identify the Active loader. Normally only one should be detected*/
369     if (pdata[11] == 0xA0) {
370       mFWInfo->chipLoaderVersion =
371           (pdata[8] << 16) | (pdata[9] << 8) | pdata[10];
372       STLOG_HAL_D("         - Most recent loader activated, revision 0x%06X",
373                   mFWInfo->chipLoaderVersion);
374     }
375     if (pdata[15] == 0xA0) {
376       mFWInfo->chipLoaderVersion =
377           (pdata[12] << 16) | (pdata[13] << 8) | pdata[14];
378       STLOG_HAL_D("         - Least recent loader activated, revision 0x%06X",
379                   mFWInfo->chipLoaderVersion);
380     }
381     if (pdata[19] == 0xA0) {
382       mFWInfo->chipLoaderVersion =
383           (pdata[16] << 16) | (pdata[17] << 8) | pdata[18];
384       STLOG_HAL_D("         - Factory loader activated, revision 0x%06X",
385                   mFWInfo->chipLoaderVersion);
386     }
387 
388     *clf_mode = FT_CLF_MODE_LOADER;
389   } else if ((pdata[2] == 0x41) && (pdata[3] == 0xA2)) {
390     STLOG_HAL_D("-> Loader V3 Mode NCI_CORE_RESET_NTF received after HW Reset");
391     mFWInfo->chipHwVersion = HW_ST54L;
392     STLOG_HAL_D("   HwVersion = 0x%02X", mFWInfo->chipHwVersion);
393     mFWInfo->chipFwVersion = 0;  // make sure FW will be updated.
394     /* retrieve Production type* from NCI_CORE_RESET_NTF */
395     mFWInfo->chipProdType = GetProdType(&pdata[44]);
396     *clf_mode = FT_CLF_MODE_LOADER;
397   } else {
398     STLOG_HAL_E(
399         "%s --> ERROR: wrong NCI_CORE_RESET_NTF received after HW Reset",
400         __func__);
401     *clf_mode = FT_CLF_MODE_ERROR;
402   }
403 
404   if ((mFWInfo->chipHwVersion == HW_ST54J) ||
405       (mFWInfo->chipHwVersion == HW_ST54L)) {
406     if ((mFwFileBin != NULL) &&
407         (mFWInfo->fileFwVersion != mFWInfo->chipFwVersion)) {
408       STLOG_HAL_D("---> Firmware update needed\n");
409       result |= FW_UPDATE_NEEDED;
410     } else {
411       STLOG_HAL_D("---> No Firmware update needed\n");
412     }
413 
414     if ((mFWInfo->fileCustVersion != 0) &&
415         (mFWInfo->chipCustVersion != mFWInfo->fileCustVersion)) {
416       STLOG_HAL_D(
417           "%s - Need to apply new st21nfc custom configuration settings\n",
418           __func__);
419       if (!mCustomParamFailed) result |= CONF_UPDATE_NEEDED;
420     } else {
421       STLOG_HAL_D("%s - No need to apply custom configuration settings\n",
422                   __func__);
423     }
424   }
425   if ((mFWInfo->fileUwbVersion != 0) &&
426       (mFWInfo->fileUwbVersion != mFWInfo->chipUwbVersion)) {
427     result |= UWB_CONF_UPDATE_NEEDED;
428     STLOG_HAL_D("%s - Need to apply new uwb param configuration \n", __func__);
429     mUwbConfigNeeded = true;
430   }
431 
432   return result;
433 } /* ft_cmd_HwReset */
434 
ExitHibernateHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)435 void ExitHibernateHandler(HALHANDLE mHalHandle, uint16_t data_len,
436                           uint8_t *p_data) {
437   STLOG_HAL_D("%s - Enter", __func__);
438   if (data_len < 3) {
439     STLOG_HAL_E("%s - Error, too short data (%d)", __func__, data_len);
440     return;
441   }
442   switch (p_data[0]) {
443     case 0x40:  //
444       STLOG_HAL_D("%s - hibernate_exited = %d ", __func__,
445                   mFWInfo->hibernate_exited);
446 
447       // CORE_INIT_RSP
448       if ((p_data[1] == 0x1) && (p_data[3] == 0x0) &&
449           (mFWInfo->hibernate_exited == 0)) {
450         // Send PROP_NFC_MODE_SET_CMD(ON)
451         if (!HalSendDownstream(mHalHandle, propNfcModeSetCmdOn,
452                                sizeof(propNfcModeSetCmdOn))) {
453           STLOG_HAL_E("%s - SendDownstream failed", __func__);
454         }
455       } else if ((p_data[1] == 0x1) && (p_data[3] == 0x0) &&
456                  (mFWInfo->hibernate_exited == 1)) {
457         STLOG_HAL_D(
458             "%s - send NCI_PROP_NFC_FW_UPDATE_CMD and use 100 ms timer for "
459             "each cmd from here",
460             __func__);
461 
462         if (!HalSendDownstreamTimer(mHalHandle, NciPropNfcFwUpdate,
463                                     sizeof(NciPropNfcFwUpdate),
464                                     FW_TIMER_DURATION)) {
465           STLOG_HAL_E("%s  SendDownstream failed", __func__);
466         }
467       } else if (p_data[3] != 0x00) {
468         STLOG_HAL_D("%s - Wrong response. Retry HW reset", __func__);
469         I2cResetPulse();
470         hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
471       }
472       break;
473 
474     case 0x4f:  //
475       if ((p_data[1] == 0x02) && (p_data[3] == 0x00) &&
476           (mFWInfo->hibernate_exited == 1)) {
477         STLOG_HAL_D("%s - NCI_PROP_NFC_FW_RSP : loader mode", __func__);
478         I2cResetPulse();
479         hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
480       } else if (p_data[3] != 0x00) {
481         STLOG_HAL_D("%s - Wrong response. Retry HW reset", __func__);
482         I2cResetPulse();
483         hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
484       }
485       break;
486     case 0x60:  //
487       if (p_data[3] == 0x2) {
488         STLOG_HAL_D("%s - CORE_RESET_NTF : after core_reset_cmd", __func__);
489 
490         if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
491           STLOG_HAL_E("%s - SendDownstream failed", __func__);
492         }
493       } else if (p_data[3] == 0xa0) {
494         mFWInfo->hibernate_exited = 1;
495         STLOG_HAL_D("%s - hibernate_exited = %d ", __func__,
496                     mFWInfo->hibernate_exited);
497 
498         if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
499           STLOG_HAL_E("%s - SendDownstream failed", __func__);
500         }
501       }
502       break;
503   }
504 }
505 
ft_CheckUWBConf()506 bool ft_CheckUWBConf() {
507 
508   char uwbLibName[256];
509   STLOG_HAL_D("%s", __func__);
510 
511   if (!GetStrValue(NAME_STNFC_UWB_LIB_NAME, (char *)uwbLibName,
512                    sizeof(uwbLibName))) {
513     STLOG_HAL_D(
514         "%s - UWB conf library name not found in conf. use default name ", __func__);
515     strcpy(uwbLibName, "/vendor/lib64/libqorvo_uwb_params_nfcc.so");
516   }
517 
518   STLOG_HAL_D("%s - UWB conf library = %s", __func__, uwbLibName);
519 
520   void *stdll = dlopen(uwbLibName, RTLD_NOW);
521   if (stdll) {
522     STLoadUwbParams fn =
523         (STLoadUwbParams)dlsym(stdll, "load_uwb_params_from_files");
524   if (fn) {
525     size_t lengthOutput =
526         fn(nciPropSetUwbConfig + 9, 100);
527     STLOG_HAL_D("%s: lengthOutput = %zu", __func__, lengthOutput);
528     if (lengthOutput > 0) {
529       memcpy(nciPropSetUwbConfig, nciHeaderPropSetUwbConfig, 9);
530       nciPropSetUwbConfig[2] = lengthOutput + 6;
531       nciPropSetUwbConfig[8] = lengthOutput;
532       mFWInfo->fileUwbVersion =
533           nciPropSetUwbConfig[9] << 8 | nciPropSetUwbConfig[10];
534       STLOG_HAL_D("%s --> uwb configuration version 0x%04X \n", __func__,
535                   mFWInfo->fileUwbVersion);
536       return true;
537     } else {
538       STLOG_HAL_D("%s: lengthOutput null", __func__);
539     }
540    }
541   } else {
542     STLOG_HAL_D("libqorvo_uwb_params_nfcc not found, do nothing.");
543   }
544   return false;
545 }
546 /*******************************************************************************
547 **
548 ** Function         resetHandlerState
549 **
550 ** Description      Reset FW update state.
551 **
552 ** Parameters       void
553 **
554 **
555 *******************************************************************************/
resetHandlerState()556 void resetHandlerState() {
557   STLOG_HAL_D("%s", __func__);
558   mHalFDState = HAL_FD_STATE_AUTHENTICATE;
559   mHalFD54LState = HAL_FD_ST54L_STATE_PUY_KEYUSER;
560 }
561 
562 /*******************************************************************************
563 **
564 ** Function         UpdateHandler
565 **
566 ** Description      Handler to update ST54J NFCC FW.
567 **
568 ** Parameters       mHalHandle - HAL handle
569 **                  data_len   - Buffer length
570 **                  p_data     - Data buffer from NFCC
571 **
572 **
573 *******************************************************************************/
UpdateHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)574 void UpdateHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t *p_data) {
575   HalSendDownstreamStopTimer(mHalHandle);
576 
577   switch (mHalFDState) {
578     case HAL_FD_STATE_AUTHENTICATE:
579       STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_AUTHENTICATE", __func__);
580 
581       if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
582         STLOG_HAL_D("%s - send APDU_AUTHENTICATION_CMD", __func__);
583         if (!HalSendDownstreamTimer(mHalHandle, (uint8_t *)mApduAuthent,
584                                     sizeof(mApduAuthent), FW_TIMER_DURATION)) {
585           STLOG_HAL_E("%s - SendDownstream failed", __func__);
586         }
587         mHalFDState = HAL_FD_STATE_ERASE_FLASH;
588       } else {
589         STLOG_HAL_D("%s - FW flash not succeeded", __func__);
590         SendExitLoadMode(mHalHandle);
591       }
592       break;
593 
594     case HAL_FD_STATE_ERASE_FLASH:  // 1
595       STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_ERASE_FLASH", __func__);
596 
597       if ((p_data[0] == 0x4f) && (p_data[1] == 0x04)) {
598         if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
599           STLOG_HAL_D(
600               " %s - send APDU_ERASE_FLASH_CMD (keep appli and NDEF areas)",
601               __func__);
602 
603           if (!HalSendDownstreamTimer(mHalHandle, ApduEraseNfcKeepAppliAndNdef,
604                                       sizeof(ApduEraseNfcKeepAppliAndNdef),
605                                       FW_TIMER_DURATION)) {
606             STLOG_HAL_E("%s - SendDownstream failed", __func__);
607           }
608 
609           fsetpos(mFwFileBin, &mPosInit);  // reset pos in stream
610 
611           mHalFDState = HAL_FD_STATE_SEND_RAW_APDU;
612 
613         } else {
614           STLOG_HAL_D("%s - FW flash not succeeded", __func__);
615           SendExitLoadMode(mHalHandle);
616         }
617       }
618       break;
619 
620     case HAL_FD_STATE_SEND_RAW_APDU:  // 3
621       STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_SEND_RAW_APDU", __func__);
622       if ((p_data[0] == 0x4f) && (p_data[1] == 0x04)) {
623         if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
624           mRetry = true;
625 
626           fgetpos(mFwFileBin, &mPos);  // save current position in stream
627           if ((fread(mBinData, sizeof(uint8_t), 3, mFwFileBin) == 3) &&
628               (fread(mBinData + 3, sizeof(uint8_t), mBinData[2], mFwFileBin) ==
629                mBinData[2])) {
630             if (!HalSendDownstreamTimer(mHalHandle, mBinData, mBinData[2] + 3,
631                                         FW_TIMER_DURATION)) {
632               STLOG_HAL_E("%s - SendDownstream failed", __func__);
633             }
634           } else {
635             STLOG_HAL_D("%s - EOF of FW binary", __func__);
636             SendExitLoadMode(mHalHandle);
637           }
638         } else if (mRetry == true) {
639           STLOG_HAL_D("%s - Last Tx was NOK. Retry", __func__);
640           mRetry = false;
641           fsetpos(mFwFileBin, &mPos);
642           if ((fread(mBinData, sizeof(uint8_t), 3, mFwFileBin) == 3) &&
643               (fread(mBinData + 3, sizeof(uint8_t), mBinData[2], mFwFileBin) ==
644                mBinData[2])) {
645             if (!HalSendDownstreamTimer(mHalHandle, mBinData, mBinData[2] + 3,
646                                         FW_TIMER_DURATION)) {
647               STLOG_HAL_E("%s - SendDownstream failed", __func__);
648             }
649             fgetpos(mFwFileBin, &mPos);  // save current position in stream
650           } else {
651             STLOG_HAL_D("%s - EOF of FW binary", __func__);
652             SendExitLoadMode(mHalHandle);
653           }
654         } else {
655           STLOG_HAL_D("%s - FW flash not succeeded.", __func__);
656           I2cResetPulse();
657           SendExitLoadMode(mHalHandle);
658         }
659       }
660       break;
661 
662     case HAL_FD_STATE_EXIT_APDU:  // 2
663       STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_EXIT_APDU", __func__);
664       if ((p_data[data_len - 2] != 0x90) || (p_data[data_len - 1] != 0x00)) {
665         STLOG_HAL_D(
666             "%s - Error exiting loader mode, i.e. a problem occurred"
667             "during FW update",
668             __func__);
669       }
670 
671       I2cResetPulse();
672       hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
673       mHalFDState = HAL_FD_STATE_AUTHENTICATE;
674       break;
675 
676     default:
677       STLOG_HAL_D("%s - mHalFDState = unknown", __func__);
678       STLOG_HAL_D("%s - FW flash not succeeded", __func__);
679       SendExitLoadMode(mHalHandle);
680       break;
681   }
682 }
683 
684 /*******************************************************************************
685 **
686 ** Function         UpdateHandlerST54L
687 **
688 ** Description      Handler to update ST54L NFCC FW.
689 **
690 ** Parameters       mHalHandle - HAL handle
691 **                  data_len   - Buffer length
692 **                  p_data     - Data buffer from NFCC
693 **
694 **
695 *******************************************************************************/
UpdateHandlerST54L(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)696 static void UpdateHandlerST54L(HALHANDLE mHalHandle, uint16_t data_len,
697                                uint8_t* p_data) {
698   STLOG_HAL_D("%s : Enter state = %d", __func__, mHalFD54LState);
699 
700   switch (mHalFD54LState) {
701     case HAL_FD_ST54L_STATE_PUY_KEYUSER:
702       if (!HalSendDownstreamTimer(
703               mHalHandle, (uint8_t*)ApduPutKeyUser1[mFWInfo->chipProdType],
704               sizeof(ApduPutKeyUser1[mFWInfo->chipProdType]),
705               FW_TIMER_DURATION)) {
706         STLOG_HAL_E("%s - SendDownstream failed", __func__);
707       }
708       mHalFD54LState = HAL_FD_ST54L_STATE_ERASE_UPGRADE_START;
709       break;
710 
711     case HAL_FD_ST54L_STATE_ERASE_UPGRADE_START:
712       if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
713         if (!HalSendDownstreamTimer(mHalHandle, (uint8_t*)ApduEraseUpgradeStart,
714                                     sizeof(ApduEraseUpgradeStart),
715                                     FW_TIMER_DURATION)) {
716           STLOG_HAL_E("%s - SendDownstream failed", __func__);
717         }
718         mHalFD54LState = HAL_FD_ST54L_STATE_ERASE_NFC_AREA;
719       } else {
720         STLOG_HAL_D("%s - FW flash not succeeded", __func__);
721         SendSwitchToUserMode(mHalHandle);
722       }
723       break;
724 
725     case HAL_FD_ST54L_STATE_ERASE_NFC_AREA:
726       if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
727         if (!HalSendDownstreamTimer(mHalHandle, (uint8_t*)ApduEraseNfcArea,
728                                     sizeof(ApduEraseNfcArea),
729                                     FW_TIMER_DURATION)) {
730           STLOG_HAL_E("%s - SendDownstream failed", __func__);
731         }
732         mHalFD54LState = HAL_FD_ST54L_STATE_ERASE_UPGRADE_STOP;
733       } else {
734         STLOG_HAL_D("%s - FW flash not succeeded", __func__);
735         SendSwitchToUserMode(mHalHandle);
736       }
737       break;
738 
739     case HAL_FD_ST54L_STATE_ERASE_UPGRADE_STOP:
740       if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
741         if (!HalSendDownstreamTimer(mHalHandle, (uint8_t*)ApduEraseUpgradeStop,
742                                     sizeof(ApduEraseUpgradeStop),
743                                     FW_TIMER_DURATION)) {
744           STLOG_HAL_E("%s - SendDownstream failed", __func__);
745         }
746         mHalFD54LState = HAL_FD_ST54L_STATE_SEND_RAW_APDU;
747       } else {
748         STLOG_HAL_D("%s - FW flash not succeeded", __func__);
749         SendSwitchToUserMode(mHalHandle);
750       }
751       break;
752 
753     case HAL_FD_ST54L_STATE_SEND_RAW_APDU:
754       STLOG_HAL_D("%s - mHalFDState = HAL_FD_ST54L_STATE_SEND_RAW_APDU",
755                   __func__);
756       if ((p_data[0] == 0x4f) && (p_data[1] == 0x04)) {
757         if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
758           mRetry = true;
759 
760           fgetpos(mFwFileBin, &mPos);  // save current position in stream
761           if ((fread(mBinData, sizeof(uint8_t), 3, mFwFileBin) == 3) &&
762               (fread(mBinData + 3, sizeof(uint8_t), mBinData[2], mFwFileBin) ==
763                mBinData[2])) {
764             if (!HalSendDownstreamTimer(mHalHandle, mBinData, mBinData[2] + 3,
765                                         FW_TIMER_DURATION)) {
766               STLOG_HAL_E("%s - SendDownstream failed", __func__);
767             }
768           } else {
769             STLOG_HAL_D("%s - EOF of FW binary", __func__);
770             if (!HalSendDownstreamTimer(
771                     mHalHandle, (uint8_t*)ApduSetVariousConfig,
772                     sizeof(ApduSetVariousConfig), FW_TIMER_DURATION)) {
773               STLOG_HAL_E("%s - SendDownstream failed", __func__);
774             }
775             mHalFD54LState = HAL_FD_ST54L_STATE_SET_CONFIG;
776           }
777         } else if (mRetry == true) {
778           STLOG_HAL_D("%s - Last Tx was NOK. Retry", __func__);
779           mRetry = false;
780           fsetpos(mFwFileBin, &mPos);
781           if ((fread(mBinData, sizeof(uint8_t), 3, mFwFileBin) == 3) &&
782               (fread(mBinData + 3, sizeof(uint8_t), mBinData[2], mFwFileBin) ==
783                mBinData[2])) {
784             if (!HalSendDownstreamTimer(mHalHandle, mBinData, mBinData[2] + 3,
785                                         FW_TIMER_DURATION)) {
786               STLOG_HAL_E("%s - SendDownstream failed", __func__);
787             }
788             fgetpos(mFwFileBin, &mPos);  // save current position in stream
789           } else {
790             STLOG_HAL_D("%s - EOF of FW binary", __func__);
791             if (!HalSendDownstreamTimer(
792                     mHalHandle, (uint8_t*)ApduSetVariousConfig,
793                     sizeof(ApduSetVariousConfig), FW_TIMER_DURATION)) {
794               STLOG_HAL_E("%s - SendDownstream failed", __func__);
795             }
796             mHalFD54LState = HAL_FD_ST54L_STATE_SET_CONFIG;
797           }
798         } else {
799           STLOG_HAL_D("%s - FW flash not succeeded.", __func__);
800           I2cResetPulse();
801           SendSwitchToUserMode(mHalHandle);
802         }
803       }
804       break;
805 
806     case HAL_FD_ST54L_STATE_SET_CONFIG:
807 
808       if ((p_data[0] == 0x4f) && (p_data[1] == 0x04)) {
809         SendSwitchToUserMode(mHalHandle);
810       }
811       break;
812 
813     case HAL_FD_ST54L_STATE_SWITCH_TO_USER:
814       if ((p_data[data_len - 2] != 0x90) || (p_data[data_len - 1] != 0x00)) {
815         STLOG_HAL_D(
816             "%s - Error exiting loader mode, i.e. a problem occurred during FW "
817             "update",
818             __func__);
819       }
820 
821       I2cResetPulse();
822       hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
823       mHalFD54LState = HAL_FD_ST54L_STATE_PUY_KEYUSER;
824       break;
825 
826     default:
827       STLOG_HAL_D("%s - mHalFD54LState = unknown", __func__);
828       STLOG_HAL_D("%s - FW flash not succeeded", __func__);
829       SendSwitchToUserMode(mHalHandle);
830       break;
831   }
832 }
833 
834 /*******************************************************************************
835 **
836 ** Function         FwUpdateHandler
837 **
838 ** Description      Handler to update NFCC FW.
839 **
840 ** Parameters       mHalHandle - HAL handle
841 **                  data_len   - Buffer length
842 **                  p_data     - Data buffer from NFCC
843 **
844 **
845 *******************************************************************************/
FwUpdateHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)846 void FwUpdateHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t* p_data) {
847   if (mFWInfo->chipHwVersion == HW_ST54L) {
848     UpdateHandlerST54L(mHalHandle, data_len, p_data);
849   } else {
850     UpdateHandler(mHalHandle, data_len, p_data);
851   }
852 }
853 
ApplyCustomParamHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)854 void ApplyCustomParamHandler(HALHANDLE mHalHandle, uint16_t data_len,
855                              uint8_t *p_data) {
856   STLOG_HAL_D("%s - Enter ", __func__);
857   if (data_len < 3) {
858     STLOG_HAL_E("%s : Error, too short data (%d)", __func__, data_len);
859     return;
860   }
861 
862   switch (p_data[0]) {
863     case 0x40:  //
864       // CORE_RESET_RSP
865       if ((p_data[1] == 0x0) && (p_data[3] == 0x0)) {
866         // do nothing
867       } else if ((p_data[1] == 0x1) && (p_data[3] == 0x0)) {
868         if (mFWInfo->hibernate_exited == 0) {
869           // Send a NFC mode on .
870           if (!HalSendDownstream(mHalHandle, propNfcModeSetCmdOn,
871                                  sizeof(propNfcModeSetCmdOn))) {
872             STLOG_HAL_E("%s - SendDownstream failed", __func__);
873           }
874           // CORE_INIT_RSP
875         } else if (mFWInfo->hibernate_exited == 1) {
876           if ((fread(mBinData, sizeof(uint8_t), 3, mCustomFileBin)) &&
877               (fread(mBinData + 3, sizeof(uint8_t), mBinData[2],
878                      mCustomFileBin))) {
879             if (!HalSendDownstream(mHalHandle, mBinData, mBinData[2] + 3)) {
880               STLOG_HAL_E("%s - SendDownstream failed", __func__);
881             }
882           }
883         }
884 
885       } else {
886         STLOG_HAL_D("%s - Error in custom param application", __func__);
887         mCustomParamFailed = true;
888         I2cResetPulse();
889         hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
890       }
891       break;
892 
893     case 0x4f:
894       if (mFWInfo->hibernate_exited == 1) {
895         if ((fread(mBinData, sizeof(uint8_t), 3, mCustomFileBin) == 3) &&
896             (fread(mBinData + 3, sizeof(uint8_t), mBinData[2],
897                    mCustomFileBin) == mBinData[2])) {
898           if (!HalSendDownstream(mHalHandle, mBinData, mBinData[2] + 3)) {
899             STLOG_HAL_E("%s - SendDownstream failed", __func__);
900           }
901         } else {
902           STLOG_HAL_D("%s - mCustomParamDone = %d", __func__, mCustomParamDone);
903           if (!mGetCustomerField) {
904             mGetCustomerField = true;
905             if (!HalSendDownstream(mHalHandle, nciGetPropConfig,
906                                    sizeof(nciGetPropConfig))) {
907               STLOG_HAL_E("%s - SendDownstream failed", __func__);
908             }
909             mGetCustomerField = true;
910 
911           } else if (!mCustomParamDone) {
912 
913             STLOG_HAL_D("%s - EOF of custom file.", __func__);
914             memset(nciPropSetConfig_CustomField, 0x0,
915                    sizeof(nciPropSetConfig_CustomField));
916             memcpy(nciPropSetConfig_CustomField, nciSetPropConfig, 9);
917             nciPropSetConfig_CustomField[8] = p_data[6];
918             nciPropSetConfig_CustomField[2] = p_data[6] + 6;
919             memcpy(nciPropSetConfig_CustomField + 9, p_data + 7, p_data[6]);
920             nciPropSetConfig_CustomField[13] = mFWInfo->chipUwbVersion >> 8;
921             nciPropSetConfig_CustomField[14] = mFWInfo->chipUwbVersion;
922 
923             if (!HalSendDownstream(mHalHandle, nciPropSetConfig_CustomField,
924                                    nciPropSetConfig_CustomField[2] + 3)) {
925               STLOG_HAL_E("%s - SendDownstream failed", __func__);
926             }
927 
928             mCustomParamDone = true;
929 
930           } else {
931             I2cResetPulse();
932             if (mUwbConfigNeeded) {
933               mCustomParamDone = false;
934               mGetCustomerField = false;
935               hal_wrapper_set_state(HAL_WRAPPER_STATE_APPLY_UWB_PARAM);
936             }
937           }
938         }
939       }
940 
941       // Check if an error has occurred for PROP_SET_CONFIG_CMD
942       // Only log a warning, do not exit code
943       if (p_data[3] != 0x00) {
944         STLOG_HAL_D("%s - Error in custom file, continue anyway", __func__);
945       }
946 
947       break;
948 
949     case 0x60:  //
950       if (p_data[1] == 0x0) {
951         if (p_data[3] == 0xa0) {
952           mFWInfo->hibernate_exited = 1;
953         }
954         if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
955           STLOG_HAL_E("%s - SendDownstream failed", __func__);
956         }
957 
958       } else if ((p_data[1] == 0x6) && mCustomParamDone) {
959         mCustomParamDone = false;
960         mGetCustomerField = false;
961         hal_wrapper_update_complete();
962       }
963       break;
964   }
965 }
966 
ApplyUwbParamHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)967 void ApplyUwbParamHandler(HALHANDLE mHalHandle, uint16_t data_len,
968                           uint8_t *p_data) {
969   STLOG_HAL_D("%s - Enter ", __func__);
970   if (data_len < 3) {
971     STLOG_HAL_E("%s : Error, too short data (%d)", __func__, data_len);
972     return;
973   }
974 
975   switch (p_data[0]) {
976     case 0x40:  //
977       // CORE_RESET_RSP
978       if ((p_data[1] == 0x0) && (p_data[3] == 0x0)) {
979         // do nothing
980       } else if ((p_data[1] == 0x1) && (p_data[3] == 0x0)) {
981         if (mFWInfo->hibernate_exited == 0) {
982           // Send a NFC mode on .
983           if (!HalSendDownstream(mHalHandle, propNfcModeSetCmdOn,
984                                  sizeof(propNfcModeSetCmdOn))) {
985             STLOG_HAL_E("%s - SendDownstream failed", __func__);
986           }
987           // CORE_INIT_RSP
988         } else if ((mFWInfo->hibernate_exited == 1) && !mUwbConfigDone) {
989           if (!HalSendDownstream(mHalHandle, nciPropSetUwbConfig,
990                                  nciPropSetUwbConfig[2] + 3)) {
991             STLOG_HAL_E("%s - SendDownstream failed", __func__);
992           }
993         }
994 
995       } else {
996         STLOG_HAL_D("%s - Error in uwb param application", __func__);
997         I2cResetPulse();
998         hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
999       }
1000       break;
1001 
1002     case 0x4f:
1003       if (mFWInfo->hibernate_exited == 1) {
1004         if (!mUwbConfigDone) {
1005           mUwbConfigDone = true;
1006           // Check if an error has occurred for PROP_SET_CONFIG_CMD
1007           // Only log a warning, do not exit code
1008           if (p_data[3] != 0x00) {
1009             STLOG_HAL_D("%s - Error in uwb file, continue anyway", __func__);
1010           }
1011           if (!HalSendDownstream(mHalHandle, nciGetPropConfig,
1012                                  sizeof(nciGetPropConfig))) {
1013             STLOG_HAL_E("%s - SendDownstream failed", __func__);
1014           }
1015         } else if ((p_data[1] == 0x2) && (p_data[2] == 0x0c)) {
1016           memset(nciPropSetConfig_CustomField, 0x0,
1017                  sizeof(nciPropSetConfig_CustomField));
1018           memcpy(nciPropSetConfig_CustomField, nciSetPropConfig, 9);
1019           nciPropSetConfig_CustomField[8] = p_data[6];
1020           nciPropSetConfig_CustomField[2] = p_data[6] + 6;
1021           memcpy(nciPropSetConfig_CustomField + 9, p_data + 7, p_data[6]);
1022           nciPropSetConfig_CustomField[13] = mFWInfo->fileUwbVersion >> 8;
1023           nciPropSetConfig_CustomField[14] = mFWInfo->fileUwbVersion;
1024 
1025           if (!HalSendDownstream(mHalHandle, nciPropSetConfig_CustomField,
1026                                  nciPropSetConfig_CustomField[2] + 3)) {
1027             STLOG_HAL_E("%s - SendDownstream failed", __func__);
1028           }
1029 
1030         } else {
1031           I2cResetPulse();
1032         }
1033       }
1034 
1035       break;
1036 
1037     case 0x60:  //
1038       if (p_data[1] == 0x0) {
1039         if (p_data[3] == 0xa0) {
1040           mFWInfo->hibernate_exited = 1;
1041         }
1042         if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
1043           STLOG_HAL_E("%s - SendDownstream failed", __func__);
1044         }
1045 
1046       } else if ((p_data[1] == 0x6) && mUwbConfigDone) {
1047         mUwbConfigNeeded = false;
1048         mUwbConfigDone = false;
1049         hal_wrapper_update_complete();
1050       }
1051       break;
1052   }
1053 }
1054 
SendExitLoadMode(HALHANDLE mmHalHandle)1055 void SendExitLoadMode(HALHANDLE mmHalHandle) {
1056   STLOG_HAL_D("%s - Send APDU_EXIT_LOAD_MODE_CMD", __func__);
1057 
1058   if (!HalSendDownstreamTimer(mmHalHandle, ApduExitLoadMode,
1059                               sizeof(ApduExitLoadMode), FW_TIMER_DURATION)) {
1060     STLOG_HAL_E("%s - SendDownstream failed", __func__);
1061   }
1062   mHalFDState = HAL_FD_STATE_EXIT_APDU;
1063 }
1064 
SendSwitchToUserMode(HALHANDLE mmHalHandle)1065 void SendSwitchToUserMode(HALHANDLE mmHalHandle) {
1066   STLOG_HAL_D("%s: enter", __func__);
1067 
1068   if (!HalSendDownstreamTimer(mmHalHandle, ApduSwitchToUser,
1069                               sizeof(ApduSwitchToUser), FW_TIMER_DURATION)) {
1070     STLOG_HAL_E("%s - SendDownstream failed", __func__);
1071   }
1072   mHalFD54LState = HAL_FD_ST54L_STATE_SWITCH_TO_USER;
1073 }
1074