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 static const uint8_t nciHeaderPropSetUwbConfig[9] = {
59 0x2F, 0x02, 0x00, 0x04, 0x00, 0x16, 0x01, 0x00, 0x00};
60 static const uint8_t nciGetPropConfig[8] = {0x2F, 0x02, 0x05, 0x03,
61 0x00, 0x06, 0x01, 0x00};
62 static const uint8_t nciSetPropConfig[9] = {0x2F, 0x02, 0x00, 0x04, 0x00,
63 0x06, 0x01, 0x00, 0x00};
64 static uint8_t nciPropSetUwbConfig[128];
65 static uint8_t nciPropSetConfig_CustomField[64];
66 hal_fd_state_e mHalFDState = HAL_FD_STATE_AUTHENTICATE;
67 void SendExitLoadMode(HALHANDLE mmHalHandle);
68 extern void hal_wrapper_update_complete();
69
70 typedef size_t (*STLoadUwbParams)(void *out_buff,
71 size_t buf_size);
72
73 /**
74 * Send a HW reset and decode NCI_CORE_RESET_NTF information
75 * @param pHwVersion is used to return HW version, part of NCI_CORE_RESET_NTF
76 * @param pFwVersion is used to return FW version, part of NCI_CORE_RESET_NTF
77 * @param pLoaderVersion is used to return Loader version, part of
78 * NCI_CORE_RESET_NTF
79 * @param pCustVersion si used to return Customer field value, part of
80 * NCI_CORE_RESET_NTF when in router mode
81 *
82 * @return mode: FT_CLF_MODE_ROUTER if router mode
83 * FT_CLF_MODE_LOADER if loader mode
84 * FT_CLF_MODE_ERROR if Error
85 */
86
hal_fd_init()87 int hal_fd_init() {
88 uint8_t result = 0;
89 char FwPath[256];
90 char ConfPath[256];
91 char fwBinName[256];
92 char fwConfName[256];
93
94 STLOG_HAL_D(" %s - enter", __func__);
95
96 if (!GetStrValue(NAME_STNFC_FW_PATH_STORAGE, (char *)FwPath,
97 sizeof(FwPath))) {
98 STLOG_HAL_D(
99 "%s - FW path not found in conf. use default location /vendor/firmware "
100 "\n", __func__);
101 strcpy(FwPath, "/vendor/firmware");
102 }
103
104 if (!GetStrValue(NAME_STNFC_FW_BIN_NAME, (char *)fwBinName,
105 sizeof(fwBinName))) {
106 STLOG_HAL_D(
107 "%s - FW binary file name not found in conf. use default name "
108 "/st21nfc_fw.bin \n", __func__);
109 strcpy(fwBinName, "/st21nfc_fw.bin");
110 }
111
112 if (!GetStrValue(NAME_STNFC_FW_CONF_NAME, (char *)fwConfName,
113 sizeof(fwConfName))) {
114 STLOG_HAL_D(
115 "%s - FW config file name not found in conf. use default name "
116 "/st21nfc_conf.bin \n", __func__);
117 strcpy(fwConfName, "/st21nfc_conf.bin");
118 }
119
120 // Getting information about FW patch, if any
121 strcpy(ConfPath, FwPath);
122 strncat(FwPath, fwBinName, sizeof(FwPath) - strlen(FwPath) - 1);
123 strncat(ConfPath, fwConfName, sizeof(ConfPath) - strlen(ConfPath) - 1);
124 STLOG_HAL_D("%s - FW update binary file = %s", __func__, FwPath);
125 STLOG_HAL_D("%s - FW config binary file = %s", __func__, ConfPath);
126
127 // Initializing structure holding FW patch details
128 mFWInfo = (FWInfo *)malloc(sizeof(FWInfo));
129
130 if (mFWInfo == NULL) {
131 result = 0;
132 }
133
134 memset(mFWInfo, 0, sizeof(FWInfo));
135
136 mFwFileBin = NULL;
137 mCustomFileBin = NULL;
138
139 // Check if FW patch binary file is present
140 // If not, get recovery FW patch file
141 if ((mFwFileBin = fopen((char *)FwPath, "r")) == NULL) {
142 STLOG_HAL_D("%s - %s not detected", __func__, fwBinName);
143 } else {
144 STLOG_HAL_D("%s - %s file detected\n", __func__, fwBinName);
145
146 result |= FW_PATCH_AVAILABLE;
147 fread(mBinData, sizeof(uint8_t), 4, mFwFileBin);
148 mFWInfo->patchVersion =
149 mBinData[0] << 24 | mBinData[1] << 16 | mBinData[2] << 8 | mBinData[3];
150
151 fread(mApduAuthent, sizeof(uint8_t), 24, mFwFileBin);
152
153 fgetpos(mFwFileBin, &mPosInit);
154
155 STLOG_HAL_D(
156 "%s --> st21nfc_fw integrates patch NFC FW version 0x%08X (%s)\n",
157 __func__, mFWInfo->patchVersion, FwType);
158 }
159
160 if ((mCustomFileBin = fopen((char *)ConfPath, "r")) == NULL) {
161 STLOG_HAL_D("%s - st21nfc custom configuration not detected\n", __func__);
162 } else {
163 STLOG_HAL_D("%s - %s file detected\n", __func__, ConfPath);
164 fread(mBinData, sizeof(uint8_t), 2, mCustomFileBin);
165 mFWInfo->confVersion = mBinData[0] << 8 | mBinData[1];
166 STLOG_HAL_D("%s --> st21nfc_custom configuration version 0x%04X \n",
167 __func__, mFWInfo->confVersion);
168 result |= FW_CUSTOM_PARAM_AVAILABLE;
169 }
170
171 if (ft_CheckUWBConf()) {
172 result |= FW_UWB_PARAM_AVAILABLE;
173 }
174
175 return result;
176 }
177
hal_fd_close()178 void hal_fd_close() {
179 STLOG_HAL_D(" %s -enter", __func__);
180 mCustomParamFailed = false;
181 if (mFWInfo != NULL) {
182 free(mFWInfo);
183 mFWInfo = NULL;
184 }
185 if (mFwFileBin != NULL) {
186 fclose(mFwFileBin);
187 mFwFileBin = NULL;
188 }
189 if (mCustomFileBin != NULL) {
190 fclose(mCustomFileBin);
191 mCustomFileBin = NULL;
192 }
193 }
194
195 /**
196 * Send a HW reset and decode NCI_CORE_RESET_NTF information
197 * @param pHwVersion is used to return HW version, part of NCI_CORE_RESET_NTF
198 * @param pFwVersion is used to return FW version, part of NCI_CORE_RESET_NTF
199 * @param pLoaderVersion is used to return Loader version, part of
200 * NCI_CORE_RESET_NTF
201 * @param pCustVersion si used to return Customer field value, part of
202 * NCI_CORE_RESET_NTF when in router mode
203 *
204 * @return mode: FT_CLF_MODE_ROUTER if router mode
205 * FT_CLF_MODE_LOADER if loader mode
206 * FT_CLF_MODE_ERROR if Error
207 */
208
ft_cmd_HwReset(uint8_t * pdata,uint8_t * clf_mode)209 uint8_t ft_cmd_HwReset(uint8_t *pdata, uint8_t *clf_mode) {
210 uint8_t result = 0;
211
212 STLOG_HAL_D(" %s - execution", __func__);
213
214 if ((pdata[1] == 0x0) && (pdata[3] == 0x1)) {
215 STLOG_HAL_D("-> Router Mode NCI_CORE_RESET_NTF received after HW Reset");
216
217 /* retrieve HW Version from NCI_CORE_RESET_NTF */
218 mFWInfo->hwVersion = pdata[8];
219 STLOG_HAL_D(" HwVersion = 0x%02X", mFWInfo->hwVersion);
220
221 /* retrieve FW Version from NCI_CORE_RESET_NTF */
222 mFWInfo->fwVersion =
223 (pdata[10] << 24) | (pdata[11] << 16) | (pdata[12] << 8) | pdata[13];
224 STLOG_HAL_D(" FwVersion = 0x%08X", mFWInfo->fwVersion);
225
226 /* retrieve Loader Version from NCI_CORE_RESET_NTF */
227 mFWInfo->loaderVersion = (pdata[14] << 16) | (pdata[15] << 8) | pdata[16];
228 STLOG_HAL_D(" LoaderVersion = 0x%06X", mFWInfo->loaderVersion);
229
230 /* retrieve Customer Version from NCI_CORE_RESET_NTF */
231 mFWInfo->custVersion = (pdata[31] << 8) | pdata[32];
232 STLOG_HAL_D(" CustomerVersion = 0x%04X", mFWInfo->custVersion);
233
234 /* retrieve Uwb param Version from NCI_CORE_RESET_NTF */
235 mFWInfo->uwbFwVersion = (pdata[29] << 8) | pdata[30];
236 STLOG_HAL_D(" uwbVersion = 0x%04X", mFWInfo->uwbFwVersion);
237
238 *clf_mode = FT_CLF_MODE_ROUTER;
239 } else if ((pdata[2] == 0x39) && (pdata[3] == 0xA1)) {
240 STLOG_HAL_D("-> Loader Mode NCI_CORE_RESET_NTF received after HW Reset");
241
242 /* deduce HW Version from Factory Loader version */
243 if (pdata[16] == 0x01) {
244 mFWInfo->hwVersion = 0x05; // ST54J
245 } else if (pdata[16] == 0x02) {
246 mFWInfo->hwVersion = 0x04; // ST21NFCD
247 } else {
248 mFWInfo->hwVersion = 0x03; // ST21NFCD
249 }
250 STLOG_HAL_D(" HwVersion = 0x%02X", mFWInfo->hwVersion);
251
252 /* Identify the Active loader. Normally only one should be detected*/
253 if (pdata[11] == 0xA0) {
254 mFWInfo->loaderVersion = (pdata[8] << 16) | (pdata[9] << 8) | pdata[10];
255 STLOG_HAL_D(" - Most recent loader activated, revision 0x%06X",
256 mFWInfo->loaderVersion);
257 }
258 if (pdata[15] == 0xA0) {
259 mFWInfo->loaderVersion = (pdata[12] << 16) | (pdata[13] << 8) | pdata[14];
260 STLOG_HAL_D(" - Least recent loader activated, revision 0x%06X",
261 mFWInfo->loaderVersion);
262 }
263 if (pdata[19] == 0xA0) {
264 mFWInfo->loaderVersion = (pdata[16] << 16) | (pdata[17] << 8) | pdata[18];
265 STLOG_HAL_D(" - Factory loader activated, revision 0x%06X",
266 mFWInfo->loaderVersion);
267 }
268
269 *clf_mode = FT_CLF_MODE_LOADER;
270 } else {
271 STLOG_HAL_E(
272 "%s --> ERROR: wrong NCI_CORE_RESET_NTF received after HW Reset",
273 __func__);
274 *clf_mode = FT_CLF_MODE_ERROR;
275 }
276
277 // Allow update only for ST54J
278 if (mFWInfo->hwVersion == 0x05) {
279 if ((mFwFileBin != NULL) && (mFWInfo->patchVersion != mFWInfo->fwVersion)) {
280 STLOG_HAL_D("---> Firmware update needed\n");
281 result |= FW_UPDATE_NEEDED;
282 } else {
283 STLOG_HAL_D("---> No Firmware update needed\n");
284 }
285
286 if ((mFWInfo->confVersion != 0) &&
287 (mFWInfo->custVersion != mFWInfo->confVersion)) {
288 STLOG_HAL_D(
289 "%s - Need to apply new st21nfc custom configuration settings\n",
290 __func__);
291 if (!mCustomParamFailed) result |= CONF_UPDATE_NEEDED;
292 } else {
293 STLOG_HAL_D("%s - No need to apply custom configuration settings\n",
294 __func__);
295 }
296 }
297 if ((mFWInfo->uwbVersion != 0) &&
298 (mFWInfo->uwbVersion != mFWInfo->uwbFwVersion)) {
299 result |= UWB_CONF_UPDATE_NEEDED;
300 STLOG_HAL_D("%s - Need to apply new uwb param configuration \n", __func__);
301 mUwbConfigNeeded = true;
302 }
303
304 return result;
305 } /* ft_cmd_HwReset */
306
ExitHibernateHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)307 void ExitHibernateHandler(HALHANDLE mHalHandle, uint16_t data_len,
308 uint8_t *p_data) {
309 STLOG_HAL_D("%s - Enter", __func__);
310 if (data_len < 3) {
311 STLOG_HAL_E("%s - Error, too short data (%d)", __func__, data_len);
312 return;
313 }
314 switch (p_data[0]) {
315 case 0x40: //
316 STLOG_HAL_D("%s - hibernate_exited = %d ", __func__,
317 mFWInfo->hibernate_exited);
318
319 // CORE_INIT_RSP
320 if ((p_data[1] == 0x1) && (p_data[3] == 0x0) &&
321 (mFWInfo->hibernate_exited == 0)) {
322 // Send PROP_NFC_MODE_SET_CMD(ON)
323 if (!HalSendDownstream(mHalHandle, propNfcModeSetCmdOn,
324 sizeof(propNfcModeSetCmdOn))) {
325 STLOG_HAL_E("%s - SendDownstream failed", __func__);
326 }
327 } else if ((p_data[1] == 0x1) && (p_data[3] == 0x0) &&
328 (mFWInfo->hibernate_exited == 1)) {
329 STLOG_HAL_D(
330 "%s - send NCI_PROP_NFC_FW_UPDATE_CMD and use 100 ms timer for "
331 "each cmd from here",
332 __func__);
333
334 if (!HalSendDownstreamTimer(mHalHandle, NciPropNfcFwUpdate,
335 sizeof(NciPropNfcFwUpdate),
336 FW_TIMER_DURATION)) {
337 STLOG_HAL_E("%s SendDownstream failed", __func__);
338 }
339 } else if (p_data[3] != 0x00) {
340 STLOG_HAL_D("%s - Wrong response. Retry HW reset", __func__);
341 I2cResetPulse();
342 hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
343 }
344 break;
345
346 case 0x4f: //
347 if ((p_data[1] == 0x02) && (p_data[3] == 0x00) &&
348 (mFWInfo->hibernate_exited == 1)) {
349 STLOG_HAL_D("%s - NCI_PROP_NFC_FW_RSP : loader mode", __func__);
350 I2cResetPulse();
351 hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
352 } else if (p_data[3] != 0x00) {
353 STLOG_HAL_D("%s - Wrong response. Retry HW reset", __func__);
354 I2cResetPulse();
355 hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
356 }
357 break;
358 case 0x60: //
359 if (p_data[3] == 0x2) {
360 STLOG_HAL_D("%s - CORE_RESET_NTF : after core_reset_cmd", __func__);
361
362 if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
363 STLOG_HAL_E("%s - SendDownstream failed", __func__);
364 }
365 } else if (p_data[3] == 0xa0) {
366 mFWInfo->hibernate_exited = 1;
367 STLOG_HAL_D("%s - hibernate_exited = %d ", __func__,
368 mFWInfo->hibernate_exited);
369
370 if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
371 STLOG_HAL_E("%s - SendDownstream failed", __func__);
372 }
373 }
374 break;
375 }
376 }
377
ft_CheckUWBConf()378 bool ft_CheckUWBConf() {
379
380 char uwbLibName[256];
381 STLOG_HAL_D("%s", __func__);
382
383 if (!GetStrValue(NAME_STNFC_UWB_LIB_NAME, (char *)uwbLibName,
384 sizeof(uwbLibName))) {
385 STLOG_HAL_D(
386 "%s - UWB conf library name not found in conf. use default name ", __func__);
387 strcpy(uwbLibName, "/vendor/lib64/libqorvo_uwb_params_nfcc.so");
388 }
389
390 STLOG_HAL_D("%s - UWB conf library = %s", __func__, uwbLibName);
391
392 void *stdll = dlopen(uwbLibName, RTLD_NOW);
393 if (stdll) {
394 STLoadUwbParams fn =
395 (STLoadUwbParams)dlsym(stdll, "load_uwb_params_from_files");
396 if (fn) {
397 size_t lengthOutput =
398 fn(nciPropSetUwbConfig + 9, 100);
399 STLOG_HAL_D("%s: lengthOutput = %zu", __func__, lengthOutput);
400 if (lengthOutput > 0) {
401 memcpy(nciPropSetUwbConfig, nciHeaderPropSetUwbConfig, 9);
402 nciPropSetUwbConfig[2] = lengthOutput + 6;
403 nciPropSetUwbConfig[8] = lengthOutput;
404 mFWInfo->uwbVersion =
405 nciPropSetUwbConfig[9] << 8 | nciPropSetUwbConfig[10];
406 STLOG_HAL_D("%s --> uwb configuration version 0x%04X \n", __func__,
407 mFWInfo->uwbVersion);
408 return true;
409 } else {
410 STLOG_HAL_D("%s: lengthOutput null", __func__);
411 }
412 }
413 } else {
414 STLOG_HAL_D("libqorvo_uwb_params_nfcc not found, do nothing.");
415 }
416 return false;
417 }
resetHandlerState()418 void resetHandlerState() {
419 STLOG_HAL_D("%s", __func__);
420 mHalFDState = HAL_FD_STATE_AUTHENTICATE;
421 }
422
UpdateHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)423 void UpdateHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t *p_data) {
424 HalSendDownstreamStopTimer(mHalHandle);
425
426 switch (mHalFDState) {
427 case HAL_FD_STATE_AUTHENTICATE:
428 STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_AUTHENTICATE", __func__);
429
430 if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
431 STLOG_HAL_D("%s - send APDU_AUTHENTICATION_CMD", __func__);
432 if (!HalSendDownstreamTimer(mHalHandle, (uint8_t *)mApduAuthent,
433 sizeof(mApduAuthent), FW_TIMER_DURATION)) {
434 STLOG_HAL_E("%s - SendDownstream failed", __func__);
435 }
436 mHalFDState = HAL_FD_STATE_ERASE_FLASH;
437 } else {
438 STLOG_HAL_D("%s - FW flash not succeeded", __func__);
439 SendExitLoadMode(mHalHandle);
440 }
441 break;
442
443 case HAL_FD_STATE_ERASE_FLASH: // 1
444 STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_ERASE_FLASH", __func__);
445
446 if ((p_data[0] == 0x4f) && (p_data[1] == 0x04)) {
447 if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
448 STLOG_HAL_D(
449 " %s - send APDU_ERASE_FLASH_CMD (keep appli and NDEF areas)",
450 __func__);
451
452 if (!HalSendDownstreamTimer(mHalHandle, ApduEraseNfcKeepAppliAndNdef,
453 sizeof(ApduEraseNfcKeepAppliAndNdef),
454 FW_TIMER_DURATION)) {
455 STLOG_HAL_E("%s - SendDownstream failed", __func__);
456 }
457
458 fsetpos(mFwFileBin, &mPosInit); // reset pos in stream
459
460 mHalFDState = HAL_FD_STATE_SEND_RAW_APDU;
461
462 } else {
463 STLOG_HAL_D("%s - FW flash not succeeded", __func__);
464 SendExitLoadMode(mHalHandle);
465 }
466 }
467 break;
468
469 case HAL_FD_STATE_SEND_RAW_APDU: // 3
470 STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_SEND_RAW_APDU", __func__);
471 if ((p_data[0] == 0x4f) && (p_data[1] == 0x04)) {
472 if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
473 mRetry = true;
474
475 fgetpos(mFwFileBin, &mPos); // save current position in stream
476 if ((fread(mBinData, sizeof(uint8_t), 3, mFwFileBin) == 3) &&
477 (fread(mBinData + 3, sizeof(uint8_t), mBinData[2], mFwFileBin) ==
478 mBinData[2])) {
479 if (!HalSendDownstreamTimer(mHalHandle, mBinData, mBinData[2] + 3,
480 FW_TIMER_DURATION)) {
481 STLOG_HAL_E("%s - SendDownstream failed", __func__);
482 }
483 } else {
484 STLOG_HAL_D("%s - EOF of FW binary", __func__);
485 SendExitLoadMode(mHalHandle);
486 }
487 } else if (mRetry == true) {
488 STLOG_HAL_D("%s - Last Tx was NOK. Retry", __func__);
489 mRetry = false;
490 fsetpos(mFwFileBin, &mPos);
491 if ((fread(mBinData, sizeof(uint8_t), 3, mFwFileBin) == 3) &&
492 (fread(mBinData + 3, sizeof(uint8_t), mBinData[2], mFwFileBin) ==
493 mBinData[2])) {
494 if (!HalSendDownstreamTimer(mHalHandle, mBinData, mBinData[2] + 3,
495 FW_TIMER_DURATION)) {
496 STLOG_HAL_E("%s - SendDownstream failed", __func__);
497 }
498 fgetpos(mFwFileBin, &mPos); // save current position in stream
499 } else {
500 STLOG_HAL_D("%s - EOF of FW binary", __func__);
501 SendExitLoadMode(mHalHandle);
502 }
503 } else {
504 STLOG_HAL_D("%s - FW flash not succeeded.", __func__);
505 I2cResetPulse();
506 SendExitLoadMode(mHalHandle);
507 }
508 }
509 break;
510
511 case HAL_FD_STATE_EXIT_APDU: // 2
512 STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_EXIT_APDU", __func__);
513 if ((p_data[data_len - 2] != 0x90) || (p_data[data_len - 1] != 0x00)) {
514 STLOG_HAL_D(
515 "%s - Error exiting loader mode, i.e. a problem occured during FW "
516 "update", __func__);
517 }
518
519 I2cResetPulse();
520 hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
521 mHalFDState = HAL_FD_STATE_AUTHENTICATE;
522 break;
523
524 default:
525 STLOG_HAL_D("%s - mHalFDState = unknown", __func__);
526 STLOG_HAL_D("%s - FW flash not succeeded", __func__);
527 SendExitLoadMode(mHalHandle);
528 break;
529 }
530 }
531
ApplyCustomParamHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)532 void ApplyCustomParamHandler(HALHANDLE mHalHandle, uint16_t data_len,
533 uint8_t *p_data) {
534 STLOG_HAL_D("%s - Enter ", __func__);
535 if (data_len < 3) {
536 STLOG_HAL_E("%s : Error, too short data (%d)", __func__, data_len);
537 return;
538 }
539
540 switch (p_data[0]) {
541 case 0x40: //
542 // CORE_RESET_RSP
543 if ((p_data[1] == 0x0) && (p_data[3] == 0x0)) {
544 // do nothing
545 } else if ((p_data[1] == 0x1) && (p_data[3] == 0x0)) {
546 if (mFWInfo->hibernate_exited == 0) {
547 // Send a NFC mode on .
548 if (!HalSendDownstream(mHalHandle, propNfcModeSetCmdOn,
549 sizeof(propNfcModeSetCmdOn))) {
550 STLOG_HAL_E("%s - SendDownstream failed", __func__);
551 }
552 // CORE_INIT_RSP
553 } else if (mFWInfo->hibernate_exited == 1) {
554 if ((fread(mBinData, sizeof(uint8_t), 3, mCustomFileBin)) &&
555 (fread(mBinData + 3, sizeof(uint8_t), mBinData[2],
556 mCustomFileBin))) {
557 if (!HalSendDownstream(mHalHandle, mBinData, mBinData[2] + 3)) {
558 STLOG_HAL_E("%s - SendDownstream failed", __func__);
559 }
560 }
561 }
562
563 } else {
564 STLOG_HAL_D("%s - Error in custom param application", __func__);
565 mCustomParamFailed = true;
566 I2cResetPulse();
567 hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
568 }
569 break;
570
571 case 0x4f:
572 if (mFWInfo->hibernate_exited == 1) {
573 if ((fread(mBinData, sizeof(uint8_t), 3, mCustomFileBin) == 3) &&
574 (fread(mBinData + 3, sizeof(uint8_t), mBinData[2],
575 mCustomFileBin) == mBinData[2])) {
576 if (!HalSendDownstream(mHalHandle, mBinData, mBinData[2] + 3)) {
577 STLOG_HAL_E("%s - SendDownstream failed", __func__);
578 }
579 } else {
580 STLOG_HAL_D("%s - mCustomParamDone = %d", __func__, mCustomParamDone);
581 if (!mGetCustomerField) {
582 mGetCustomerField = true;
583 if (!HalSendDownstream(mHalHandle, nciGetPropConfig,
584 sizeof(nciGetPropConfig))) {
585 STLOG_HAL_E("%s - SendDownstream failed", __func__);
586 }
587 mGetCustomerField = true;
588
589 } else if (!mCustomParamDone) {
590
591 STLOG_HAL_D("%s - EOF of custom file.", __func__);
592 memset(nciPropSetConfig_CustomField, 0x0,
593 sizeof(nciPropSetConfig_CustomField));
594 memcpy(nciPropSetConfig_CustomField, nciSetPropConfig, 9);
595 nciPropSetConfig_CustomField[8] = p_data[6];
596 nciPropSetConfig_CustomField[2] = p_data[6] + 6;
597 memcpy(nciPropSetConfig_CustomField + 9, p_data + 7, p_data[6]);
598 nciPropSetConfig_CustomField[13] = mFWInfo->uwbFwVersion >> 8;
599 nciPropSetConfig_CustomField[14] = mFWInfo->uwbFwVersion;
600
601 if (!HalSendDownstream(mHalHandle, nciPropSetConfig_CustomField,
602 nciPropSetConfig_CustomField[2] + 3)) {
603 STLOG_HAL_E("%s - SendDownstream failed", __func__);
604 }
605
606 mCustomParamDone = true;
607
608 } else {
609 I2cResetPulse();
610 if (mUwbConfigNeeded) {
611 mCustomParamDone = false;
612 mGetCustomerField = false;
613 hal_wrapper_set_state(HAL_WRAPPER_STATE_APPLY_UWB_PARAM);
614 }
615 }
616 }
617 }
618
619 // Check if an error has occurred for PROP_SET_CONFIG_CMD
620 // Only log a warning, do not exit code
621 if (p_data[3] != 0x00) {
622 STLOG_HAL_D("%s - Error in custom file, continue anyway", __func__);
623 }
624
625 break;
626
627 case 0x60: //
628 if (p_data[1] == 0x0) {
629 if (p_data[3] == 0xa0) {
630 mFWInfo->hibernate_exited = 1;
631 }
632 if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
633 STLOG_HAL_E("%s - SendDownstream failed", __func__);
634 }
635
636 } else if ((p_data[1] == 0x6) && mCustomParamDone) {
637 mCustomParamDone = false;
638 mGetCustomerField = false;
639 hal_wrapper_update_complete();
640 }
641 break;
642 }
643 }
644
ApplyUwbParamHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)645 void ApplyUwbParamHandler(HALHANDLE mHalHandle, uint16_t data_len,
646 uint8_t *p_data) {
647 STLOG_HAL_D("%s - Enter ", __func__);
648 if (data_len < 3) {
649 STLOG_HAL_E("%s : Error, too short data (%d)", __func__, data_len);
650 return;
651 }
652
653 switch (p_data[0]) {
654 case 0x40: //
655 // CORE_RESET_RSP
656 if ((p_data[1] == 0x0) && (p_data[3] == 0x0)) {
657 // do nothing
658 } else if ((p_data[1] == 0x1) && (p_data[3] == 0x0)) {
659 if (mFWInfo->hibernate_exited == 0) {
660 // Send a NFC mode on .
661 if (!HalSendDownstream(mHalHandle, propNfcModeSetCmdOn,
662 sizeof(propNfcModeSetCmdOn))) {
663 STLOG_HAL_E("%s - SendDownstream failed", __func__);
664 }
665 // CORE_INIT_RSP
666 } else if ((mFWInfo->hibernate_exited == 1) && !mUwbConfigDone) {
667 if (!HalSendDownstream(mHalHandle, nciPropSetUwbConfig,
668 nciPropSetUwbConfig[2] + 3)) {
669 STLOG_HAL_E("%s - SendDownstream failed", __func__);
670 }
671 }
672
673 } else {
674 STLOG_HAL_D("%s - Error in uwb param application", __func__);
675 I2cResetPulse();
676 hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
677 }
678 break;
679
680 case 0x4f:
681 if (mFWInfo->hibernate_exited == 1) {
682 if (!mUwbConfigDone) {
683 mUwbConfigDone = true;
684 // Check if an error has occurred for PROP_SET_CONFIG_CMD
685 // Only log a warning, do not exit code
686 if (p_data[3] != 0x00) {
687 STLOG_HAL_D("%s - Error in uwb file, continue anyway", __func__);
688 }
689 if (!HalSendDownstream(mHalHandle, nciGetPropConfig,
690 sizeof(nciGetPropConfig))) {
691 STLOG_HAL_E("%s - SendDownstream failed", __func__);
692 }
693 } else if ((p_data[1] == 0x2) && (p_data[2] == 0x0c)) {
694 memset(nciPropSetConfig_CustomField, 0x0,
695 sizeof(nciPropSetConfig_CustomField));
696 memcpy(nciPropSetConfig_CustomField, nciSetPropConfig, 9);
697 nciPropSetConfig_CustomField[8] = p_data[6];
698 nciPropSetConfig_CustomField[2] = p_data[6] + 6;
699 memcpy(nciPropSetConfig_CustomField + 9, p_data + 7, p_data[6]);
700 nciPropSetConfig_CustomField[13] = mFWInfo->uwbVersion >> 8;
701 nciPropSetConfig_CustomField[14] = mFWInfo->uwbVersion;
702
703 if (!HalSendDownstream(mHalHandle, nciPropSetConfig_CustomField,
704 nciPropSetConfig_CustomField[2] + 3)) {
705 STLOG_HAL_E("%s - SendDownstream failed", __func__);
706 }
707
708 } else {
709 I2cResetPulse();
710 }
711 }
712
713 break;
714
715 case 0x60: //
716 if (p_data[1] == 0x0) {
717 if (p_data[3] == 0xa0) {
718 mFWInfo->hibernate_exited = 1;
719 }
720 if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
721 STLOG_HAL_E("%s - SendDownstream failed", __func__);
722 }
723
724 } else if ((p_data[1] == 0x6) && mUwbConfigDone) {
725 mUwbConfigNeeded = false;
726 mUwbConfigDone = false;
727 hal_wrapper_update_complete();
728 }
729 break;
730 }
731 }
732
SendExitLoadMode(HALHANDLE mmHalHandle)733 void SendExitLoadMode(HALHANDLE mmHalHandle) {
734 STLOG_HAL_D("%s - Send APDU_EXIT_LOAD_MODE_CMD", __func__);
735
736 if (!HalSendDownstreamTimer(mmHalHandle, ApduExitLoadMode,
737 sizeof(ApduExitLoadMode), FW_TIMER_DURATION)) {
738 STLOG_HAL_E("%s - SendDownstream failed", __func__);
739 }
740 mHalFDState = HAL_FD_STATE_EXIT_APDU;
741 }
742