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 <errno.h>
23 #include <hardware/nfc.h>
24 #include <string.h>
25 #include "android_logmsg.h"
26 #include "halcore.h"
27 /* Initialize fw info structure pointer used to access fw info structure */
28 FWInfo *mFWInfo = NULL;
29 FILE *mFwFileBin;
30 FILE *mCustomFileBin;
31 fpos_t mPos;
32 fpos_t mPosInit;
33 uint8_t mBinData[260];
34 bool mRetry = true;
35 bool mCustomParamFailed = false;
36 bool mCustomParamDone = false;
37 uint8_t *pCmd;
38 int mFWRecovCount = 0;
39 const char *FwType = "generic";
40 char mApduAuthent[24];
41
42 static const uint8_t propNfcModeSetCmdOn[] = {0x2f, 0x02, 0x02, 0x02, 0x01};
43 static const uint8_t coreInitCmd[] = {0x20, 0x01, 0x02, 0x00, 0x00};
44 static const uint8_t NciPropNfcFwUpdate[] = {0x2F, 0x02, 0x05, 0x06,
45 0x00, 0x01, 0x02, 0x03};
46
47 static uint8_t ApduEraseNfcKeepAppliAndNdef[] = {
48 0x2F, 0x04, 0x16, 0x80, 0x0C, 0x00, 0x00, 0x11, 0x05,
49 0x00, 0x23, 0xDF, 0x00, 0x00, 0x23, 0xDF, 0xFF, 0x00,
50 0x23, 0xE0, 0x00, 0x00, 0x23, 0xFF, 0xFF};
51
52 static const uint8_t ApduExitLoadMode[] = {0x2F, 0x04, 0x06, 0x80, 0xA0,
53 0x00, 0x00, 0x01, 0x01};
54
55 hal_fd_state_e mHalFDState = HAL_FD_STATE_AUTHENTICATE;
56 void SendExitLoadMode(HALHANDLE mmHalHandle);
57 extern void hal_wrapper_update_complete();
58
59 /**
60 * Send a HW reset and decode NCI_CORE_RESET_NTF information
61 * @param pHwVersion is used to return HW version, part of NCI_CORE_RESET_NTF
62 * @param pFwVersion is used to return FW version, part of NCI_CORE_RESET_NTF
63 * @param pLoaderVersion is used to return Loader version, part of
64 * NCI_CORE_RESET_NTF
65 * @param pCustVersion si used to return Customer field value, part of
66 * NCI_CORE_RESET_NTF when in router mode
67 *
68 * @return mode: FT_CLF_MODE_ROUTER if router mode
69 * FT_CLF_MODE_LOADER if loader mode
70 * FT_CLF_MODE_ERROR if Error
71 */
72
hal_fd_init()73 int hal_fd_init() {
74 uint8_t result = 0;
75 char FwPath[256];
76 char ConfPath[256];
77 char fwBinName[256];
78 char fwConfName[256];
79
80 STLOG_HAL_D(" %s - enter", __func__);
81
82 if (!GetStrValue(NAME_STNFC_FW_PATH_STORAGE, (char *)FwPath,
83 sizeof(FwPath))) {
84 STLOG_HAL_D(
85 "%s - FW path not found in conf. use default location /vendor/firmware "
86 "\n", __func__);
87 strcpy(FwPath, "/vendor/firmware");
88 }
89
90 if (!GetStrValue(NAME_STNFC_FW_BIN_NAME, (char *)fwBinName,
91 sizeof(fwBinName))) {
92 STLOG_HAL_D(
93 "%s - FW binary file name not found in conf. use default name "
94 "/st21nfc_fw.bin \n", __func__);
95 strcpy(fwBinName, "/st21nfc_fw.bin");
96 }
97
98 if (!GetStrValue(NAME_STNFC_FW_CONF_NAME, (char *)fwConfName,
99 sizeof(fwConfName))) {
100 STLOG_HAL_D(
101 "%s - FW config file name not found in conf. use default name "
102 "/st21nfc_conf.bin \n", __func__);
103 strcpy(fwConfName, "/st21nfc_conf.bin");
104 }
105
106 // Getting information about FW patch, if any
107 strcpy(ConfPath, FwPath);
108 strncat(FwPath, fwBinName, sizeof(FwPath) - strlen(FwPath) - 1);
109 strncat(ConfPath, fwConfName, sizeof(ConfPath) - strlen(ConfPath) - 1);
110 STLOG_HAL_D("%s - FW update binary file = %s", __func__, FwPath);
111 STLOG_HAL_D("%s - FW config binary file = %s", __func__, ConfPath);
112
113 // Initializing structure holding FW patch details
114 mFWInfo = (FWInfo *)malloc(sizeof(FWInfo));
115
116 if (mFWInfo == NULL) {
117 result = 0;
118 }
119
120 memset(mFWInfo, 0, sizeof(FWInfo));
121
122 mFwFileBin = NULL;
123 mCustomFileBin = NULL;
124
125 // Check if FW patch binary file is present
126 // If not, get recovery FW patch file
127 if ((mFwFileBin = fopen((char *)FwPath, "r")) == NULL) {
128 STLOG_HAL_D("%s - %s not detected", __func__, fwBinName);
129 } else {
130 STLOG_HAL_D("%s - %s file detected\n", __func__, fwBinName);
131
132 result |= FW_PATCH_AVAILABLE;
133 fread(mBinData, sizeof(uint8_t), 4, mFwFileBin);
134 mFWInfo->patchVersion =
135 mBinData[0] << 24 | mBinData[1] << 16 | mBinData[2] << 8 | mBinData[3];
136
137 fread(mApduAuthent, sizeof(uint8_t), 24, mFwFileBin);
138
139 fgetpos(mFwFileBin, &mPosInit);
140
141 STLOG_HAL_D(
142 "%s --> st21nfc_fw integrates patch NFC FW version 0x%08X (%s)\n",
143 __func__, mFWInfo->patchVersion, FwType);
144 }
145
146 if ((mCustomFileBin = fopen((char *)ConfPath, "r")) == NULL) {
147 STLOG_HAL_D("%s - st21nfc custom configuration not detected\n", __func__);
148 } else {
149 STLOG_HAL_D("%s - %s file detected\n", __func__, ConfPath);
150 fread(mBinData, sizeof(uint8_t), 2, mCustomFileBin);
151 mFWInfo->confVersion = mBinData[0] << 8 | mBinData[1];
152 STLOG_HAL_D("%s --> st21nfc_custom configuration version 0x%04X \n",
153 __func__, mFWInfo->confVersion);
154 result |= FW_CUSTOM_PARAM_AVAILABLE;
155 }
156
157 return result;
158 }
159
hal_fd_close()160 void hal_fd_close() {
161 STLOG_HAL_D(" %s -enter", __func__);
162 mCustomParamFailed = false;
163 if (mFWInfo != NULL) {
164 free(mFWInfo);
165 mFWInfo = NULL;
166 }
167 if (mFwFileBin != NULL) {
168 fclose(mFwFileBin);
169 mFwFileBin = NULL;
170 }
171 if (mCustomFileBin != NULL) {
172 fclose(mCustomFileBin);
173 mCustomFileBin = NULL;
174 }
175 }
176
177 /**
178 * Send a HW reset and decode NCI_CORE_RESET_NTF information
179 * @param pHwVersion is used to return HW version, part of NCI_CORE_RESET_NTF
180 * @param pFwVersion is used to return FW version, part of NCI_CORE_RESET_NTF
181 * @param pLoaderVersion is used to return Loader version, part of
182 * NCI_CORE_RESET_NTF
183 * @param pCustVersion si used to return Customer field value, part of
184 * NCI_CORE_RESET_NTF when in router mode
185 *
186 * @return mode: FT_CLF_MODE_ROUTER if router mode
187 * FT_CLF_MODE_LOADER if loader mode
188 * FT_CLF_MODE_ERROR if Error
189 */
190
ft_cmd_HwReset(uint8_t * pdata,uint8_t * clf_mode)191 uint8_t ft_cmd_HwReset(uint8_t *pdata, uint8_t *clf_mode) {
192 uint8_t result = 0;
193
194 STLOG_HAL_D(" %s - execution", __func__);
195
196 if ((pdata[1] == 0x0) && (pdata[3] == 0x1)) {
197 STLOG_HAL_D("-> Router Mode NCI_CORE_RESET_NTF received after HW Reset");
198
199 /* retrieve HW Version from NCI_CORE_RESET_NTF */
200 mFWInfo->hwVersion = pdata[8];
201 STLOG_HAL_D(" HwVersion = 0x%02X", mFWInfo->hwVersion);
202
203 /* retrieve FW Version from NCI_CORE_RESET_NTF */
204 mFWInfo->fwVersion =
205 (pdata[10] << 24) | (pdata[11] << 16) | (pdata[12] << 8) | pdata[13];
206 STLOG_HAL_D(" FwVersion = 0x%08X", mFWInfo->fwVersion);
207
208 /* retrieve Loader Version from NCI_CORE_RESET_NTF */
209 mFWInfo->loaderVersion = (pdata[14] << 16) | (pdata[15] << 8) | pdata[16];
210 STLOG_HAL_D(" LoaderVersion = 0x%06X", mFWInfo->loaderVersion);
211
212 /* retrieve Customer Version from NCI_CORE_RESET_NTF */
213 mFWInfo->custVersion = (pdata[31] << 8) | pdata[32];
214 STLOG_HAL_D(" CustomerVersion = 0x%04X", mFWInfo->custVersion);
215
216 *clf_mode = FT_CLF_MODE_ROUTER;
217 } else if ((pdata[2] == 0x39) && (pdata[3] == 0xA1)) {
218 STLOG_HAL_D("-> Loader Mode NCI_CORE_RESET_NTF received after HW Reset");
219
220 /* deduce HW Version from Factory Loader version */
221 if (pdata[16] == 0x01) {
222 mFWInfo->hwVersion = 0x05; // ST54J
223 } else if (pdata[16] == 0x02) {
224 mFWInfo->hwVersion = 0x04; // ST21NFCD
225 } else {
226 mFWInfo->hwVersion = 0x03; // ST21NFCD
227 }
228 STLOG_HAL_D(" HwVersion = 0x%02X", mFWInfo->hwVersion);
229
230 /* Identify the Active loader. Normally only one should be detected*/
231 if (pdata[11] == 0xA0) {
232 mFWInfo->loaderVersion = (pdata[8] << 16) | (pdata[9] << 8) | pdata[10];
233 STLOG_HAL_D(" - Most recent loader activated, revision 0x%06X",
234 mFWInfo->loaderVersion);
235 }
236 if (pdata[15] == 0xA0) {
237 mFWInfo->loaderVersion = (pdata[12] << 16) | (pdata[13] << 8) | pdata[14];
238 STLOG_HAL_D(" - Least recent loader activated, revision 0x%06X",
239 mFWInfo->loaderVersion);
240 }
241 if (pdata[19] == 0xA0) {
242 mFWInfo->loaderVersion = (pdata[16] << 16) | (pdata[17] << 8) | pdata[18];
243 STLOG_HAL_D(" - Factory loader activated, revision 0x%06X",
244 mFWInfo->loaderVersion);
245 }
246
247 *clf_mode = FT_CLF_MODE_LOADER;
248 } else {
249 STLOG_HAL_E(
250 "%s --> ERROR: wrong NCI_CORE_RESET_NTF received after HW Reset",
251 __func__);
252 *clf_mode = FT_CLF_MODE_ERROR;
253 }
254
255 // Allow update only for ST54J
256 if (mFWInfo->hwVersion == 0x05) {
257 if ((mFwFileBin != NULL) && (mFWInfo->patchVersion != mFWInfo->fwVersion)) {
258 STLOG_HAL_D("---> Firmware update needed\n");
259 result |= FW_UPDATE_NEEDED;
260 } else {
261 STLOG_HAL_D("---> No Firmware update needed\n");
262 }
263
264 if ((mFWInfo->confVersion != 0) &&
265 (mFWInfo->custVersion != mFWInfo->confVersion)) {
266 STLOG_HAL_D(
267 "%s - Need to apply new st21nfc custom configuration settings\n",
268 __func__);
269 if (!mCustomParamFailed) result |= CONF_UPDATE_NEEDED;
270 } else {
271 STLOG_HAL_D("%s - No need to apply custom configuration settings\n",
272 __func__);
273 }
274 }
275
276 return result;
277 } /* ft_cmd_HwReset */
278
ExitHibernateHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)279 void ExitHibernateHandler(HALHANDLE mHalHandle, uint16_t data_len,
280 uint8_t *p_data) {
281 STLOG_HAL_D("%s - Enter", __func__);
282 if (data_len < 3) {
283 STLOG_HAL_E("%s - Error, too short data (%d)", __func__, data_len);
284 return;
285 }
286 switch (p_data[0]) {
287 case 0x40: //
288 STLOG_HAL_D("%s - hibernate_exited = %d ", __func__,
289 mFWInfo->hibernate_exited);
290
291 // CORE_INIT_RSP
292 if ((p_data[1] == 0x1) && (p_data[3] == 0x0) &&
293 (mFWInfo->hibernate_exited == 0)) {
294 // Send PROP_NFC_MODE_SET_CMD(ON)
295 if (!HalSendDownstream(mHalHandle, propNfcModeSetCmdOn,
296 sizeof(propNfcModeSetCmdOn))) {
297 STLOG_HAL_E("%s - SendDownstream failed", __func__);
298 }
299 } else if ((p_data[1] == 0x1) && (p_data[3] == 0x0) &&
300 (mFWInfo->hibernate_exited == 1)) {
301 STLOG_HAL_D(
302 "%s - send NCI_PROP_NFC_FW_UPDATE_CMD and use 100 ms timer for "
303 "each cmd from here",
304 __func__);
305
306 if (!HalSendDownstreamTimer(mHalHandle, NciPropNfcFwUpdate,
307 sizeof(NciPropNfcFwUpdate),
308 FW_TIMER_DURATION)) {
309 STLOG_HAL_E("%s SendDownstream failed", __func__);
310 }
311 } else if (p_data[3] != 0x00) {
312 STLOG_HAL_D("%s - Wrong response. Retry HW reset", __func__);
313 I2cResetPulse();
314 hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
315 }
316 break;
317
318 case 0x4f: //
319 if ((p_data[1] == 0x02) && (p_data[3] == 0x00) &&
320 (mFWInfo->hibernate_exited == 1)) {
321 STLOG_HAL_D("%s - NCI_PROP_NFC_FW_RSP : loader mode", __func__);
322 I2cResetPulse();
323 hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
324 } else if (p_data[3] != 0x00) {
325 STLOG_HAL_D("%s - Wrong response. Retry HW reset", __func__);
326 I2cResetPulse();
327 hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
328 }
329 break;
330 case 0x60: //
331 if (p_data[3] == 0x2) {
332 STLOG_HAL_D("%s - CORE_RESET_NTF : after core_reset_cmd", __func__);
333
334 if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
335 STLOG_HAL_E("%s - SendDownstream failed", __func__);
336 }
337 } else if (p_data[3] == 0xa0) {
338 mFWInfo->hibernate_exited = 1;
339 STLOG_HAL_D("%s - hibernate_exited = %d ", __func__,
340 mFWInfo->hibernate_exited);
341
342 if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
343 STLOG_HAL_E("%s - SendDownstream failed", __func__);
344 }
345 }
346 break;
347 }
348 }
349
resetHandlerState()350 void resetHandlerState() {
351 STLOG_HAL_D("%s", __func__);
352 mHalFDState = HAL_FD_STATE_AUTHENTICATE;
353 }
354
UpdateHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)355 void UpdateHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t *p_data) {
356 HalSendDownstreamStopTimer(mHalHandle);
357
358 switch (mHalFDState) {
359 case HAL_FD_STATE_AUTHENTICATE:
360 STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_AUTHENTICATE", __func__);
361
362 if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
363 STLOG_HAL_D("%s - send APDU_AUTHENTICATION_CMD", __func__);
364 if (!HalSendDownstreamTimer(mHalHandle, (uint8_t *)mApduAuthent,
365 sizeof(mApduAuthent), FW_TIMER_DURATION)) {
366 STLOG_HAL_E("%s - SendDownstream failed", __func__);
367 }
368 mHalFDState = HAL_FD_STATE_ERASE_FLASH;
369 } else {
370 STLOG_HAL_D("%s - FW flash not succeeded", __func__);
371 SendExitLoadMode(mHalHandle);
372 }
373 break;
374
375 case HAL_FD_STATE_ERASE_FLASH: // 1
376 STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_ERASE_FLASH", __func__);
377
378 if ((p_data[0] == 0x4f) && (p_data[1] == 0x04)) {
379 if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
380 STLOG_HAL_D(
381 " %s - send APDU_ERASE_FLASH_CMD (keep appli and NDEF areas)",
382 __func__);
383
384 if (!HalSendDownstreamTimer(mHalHandle, ApduEraseNfcKeepAppliAndNdef,
385 sizeof(ApduEraseNfcKeepAppliAndNdef),
386 FW_TIMER_DURATION)) {
387 STLOG_HAL_E("%s - SendDownstream failed", __func__);
388 }
389
390 fsetpos(mFwFileBin, &mPosInit); // reset pos in stream
391
392 mHalFDState = HAL_FD_STATE_SEND_RAW_APDU;
393
394 } else {
395 STLOG_HAL_D("%s - FW flash not succeeded", __func__);
396 SendExitLoadMode(mHalHandle);
397 }
398 }
399 break;
400
401 case HAL_FD_STATE_SEND_RAW_APDU: // 3
402 STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_SEND_RAW_APDU", __func__);
403 if ((p_data[0] == 0x4f) && (p_data[1] == 0x04)) {
404 if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
405 mRetry = true;
406
407 fgetpos(mFwFileBin, &mPos); // save current position in stream
408 if ((fread(mBinData, sizeof(uint8_t), 3, mFwFileBin) == 3) &&
409 (fread(mBinData + 3, sizeof(uint8_t), mBinData[2], mFwFileBin) ==
410 mBinData[2])) {
411 if (!HalSendDownstreamTimer(mHalHandle, mBinData, mBinData[2] + 3,
412 FW_TIMER_DURATION)) {
413 STLOG_HAL_E("%s - SendDownstream failed", __func__);
414 }
415 } else {
416 STLOG_HAL_D("%s - EOF of FW binary", __func__);
417 SendExitLoadMode(mHalHandle);
418 }
419 } else if (mRetry == true) {
420 STLOG_HAL_D("%s - Last Tx was NOK. Retry", __func__);
421 mRetry = false;
422 fsetpos(mFwFileBin, &mPos);
423 if ((fread(mBinData, sizeof(uint8_t), 3, mFwFileBin) == 3) &&
424 (fread(mBinData + 3, sizeof(uint8_t), mBinData[2], mFwFileBin) ==
425 mBinData[2])) {
426 if (!HalSendDownstreamTimer(mHalHandle, mBinData, mBinData[2] + 3,
427 FW_TIMER_DURATION)) {
428 STLOG_HAL_E("%s - SendDownstream failed", __func__);
429 }
430 fgetpos(mFwFileBin, &mPos); // save current position in stream
431 } else {
432 STLOG_HAL_D("%s - EOF of FW binary", __func__);
433 SendExitLoadMode(mHalHandle);
434 }
435 } else {
436 STLOG_HAL_D("%s - FW flash not succeeded.", __func__);
437 I2cResetPulse();
438 SendExitLoadMode(mHalHandle);
439 }
440 }
441 break;
442
443 case HAL_FD_STATE_EXIT_APDU: // 2
444 STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_EXIT_APDU", __func__);
445 if ((p_data[data_len - 2] != 0x90) || (p_data[data_len - 1] != 0x00)) {
446 STLOG_HAL_D(
447 "%s - Error exiting loader mode, i.e. a problem occured during FW "
448 "update", __func__);
449 }
450
451 I2cResetPulse();
452 hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
453 mHalFDState = HAL_FD_STATE_AUTHENTICATE;
454 break;
455
456 default:
457 STLOG_HAL_D("%s - mHalFDState = unknown", __func__);
458 STLOG_HAL_D("%s - FW flash not succeeded", __func__);
459 SendExitLoadMode(mHalHandle);
460 break;
461 }
462 }
463
ApplyCustomParamHandler(HALHANDLE mHalHandle,uint16_t data_len,uint8_t * p_data)464 void ApplyCustomParamHandler(HALHANDLE mHalHandle, uint16_t data_len,
465 uint8_t *p_data) {
466 STLOG_HAL_D("%s - Enter ", __func__);
467 if (data_len < 3) {
468 STLOG_HAL_E("%s : Error, too short data (%d)", __func__, data_len);
469 return;
470 }
471
472 switch (p_data[0]) {
473 case 0x40: //
474 // CORE_RESET_RSP
475 if ((p_data[1] == 0x0) && (p_data[3] == 0x0)) {
476 // do nothing
477 } else if ((p_data[1] == 0x1) && (p_data[3] == 0x0)) {
478 if (mFWInfo->hibernate_exited == 0) {
479 // Send a NFC mode on .
480 if (!HalSendDownstream(mHalHandle, propNfcModeSetCmdOn,
481 sizeof(propNfcModeSetCmdOn))) {
482 STLOG_HAL_E("%s - SendDownstream failed", __func__);
483 }
484 // CORE_INIT_RSP
485 } else if (mFWInfo->hibernate_exited == 1) {
486 if ((fread(mBinData, sizeof(uint8_t), 3, mCustomFileBin)) &&
487 (fread(mBinData + 3, sizeof(uint8_t), mBinData[2],
488 mCustomFileBin))) {
489 if (!HalSendDownstream(mHalHandle, mBinData, mBinData[2] + 3)) {
490 STLOG_HAL_E("%s - SendDownstream failed", __func__);
491 }
492 }
493 }
494
495 } else {
496 STLOG_HAL_D("%s - Error in custom param application", __func__);
497 mCustomParamFailed = true;
498 I2cResetPulse();
499 hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
500 }
501 break;
502
503 case 0x4f:
504 if (mFWInfo->hibernate_exited == 1) {
505 if ((fread(mBinData, sizeof(uint8_t), 3, mCustomFileBin) == 3) &&
506 (fread(mBinData + 3, sizeof(uint8_t), mBinData[2],
507 mCustomFileBin) == mBinData[2])) {
508 if (!HalSendDownstream(mHalHandle, mBinData, mBinData[2] + 3)) {
509 STLOG_HAL_E("%s - SendDownstream failed", __func__);
510 }
511 } else {
512 STLOG_HAL_D("%s - EOF of custom file", __func__);
513 mCustomParamDone = true;
514 I2cResetPulse();
515 }
516
517 // Check if an error has occured for PROP_SET_CONFIG_CMD
518 // Only log a warning, do not exit code
519 if (p_data[3] != 0x00) {
520 STLOG_HAL_D("%s - Error in custom file, continue anyway", __func__);
521 }
522 }
523 break;
524
525 case 0x60: //
526 if (p_data[1] == 0x0) {
527 if (p_data[3] == 0xa0) {
528 mFWInfo->hibernate_exited = 1;
529 }
530 if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
531 STLOG_HAL_E("%s - SendDownstream failed", __func__);
532 }
533
534 } else if ((p_data[1] == 0x6) && mCustomParamDone) {
535 mCustomParamDone = false;
536 hal_wrapper_update_complete();
537 }
538 break;
539 }
540 }
541
SendExitLoadMode(HALHANDLE mmHalHandle)542 void SendExitLoadMode(HALHANDLE mmHalHandle) {
543 STLOG_HAL_D("%s - Send APDU_EXIT_LOAD_MODE_CMD", __func__);
544
545 if (!HalSendDownstreamTimer(mmHalHandle, ApduExitLoadMode,
546 sizeof(ApduExitLoadMode), FW_TIMER_DURATION)) {
547 STLOG_HAL_E("%s - SendDownstream failed", __func__);
548 }
549 mHalFDState = HAL_FD_STATE_EXIT_APDU;
550 }
551