1 /*
2 * Copyright 2018-2022 NXP
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18 /*************************************************************************************/
19 /* INCLUDES */
20 /*************************************************************************************/
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <ctype.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <sys/ioctl.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <string>
31 #include "phNxpLog.h"
32 #include <cstring>
33 #include <iostream>
34 #include <sstream>
35 #include <phTmlUwb_spi.h>
36 #include "phNxpUciHal_fwd.h"
37 #include <phNxpUciHal_utils.h>
38 #include "phNxpConfig.h"
39 using namespace std;
40 #define FILEPATH_MAXLEN 500
41
42 static uint8_t chip_id = 0x00;
43 static uint8_t deviceLcInfo = 0x00;
44 static uint8_t is_fw_download_log_enabled = 0x00;
45 const char* default_prod_fw = "libsr100t_prod_fw.bin";
46 const char* default_dev_fw = "libsr100t_dev_fw.bin";
47
48 char* configured_fw_name = NULL;
49 char default_fw_path[FILEPATH_MAXLEN] = "/vendor/firmware/uwb/";
50 /*************************************************************************************/
51 /* LOCAL FUNCTIONS */
52 /*************************************************************************************/
setOpts(void)53 static void setOpts(void)
54 {
55 gOpts.link = Link_Default;
56 gOpts.mode = Mode_Default;
57 gOpts.capture = Capture_Default;
58 gOpts.imgFile = NULL;
59 gOpts.fImg = NULL;
60 gOpts.mosiFile = (char*)"Mosi.bin";
61 gOpts.fMosi = NULL;
62 gOpts.misoFile = (char*)"Miso.bin";
63 gOpts.fMiso = NULL;
64
65 gPasswd = FALSE;
66 gImg = FALSE;
67 }
68
69
init(void)70 static int init(void) {
71 const uint16_t fw_max_len = 260;
72 configured_fw_name = (char*)malloc(fw_max_len * sizeof(char));
73 const char *pDefaultFwFileName = NULL;
74 int maxSrcLen = (FILEPATH_MAXLEN-strlen(default_fw_path)) - 1;
75 if (configured_fw_name == NULL) {
76 ALOGD("malloc of configured_fw_name failed ");
77 return 1;
78 }
79 if((deviceLcInfo == PHHBCI_HELIOS_PROD_KEY_1) || (deviceLcInfo == PHHBCI_HELIOS_PROD_KEY_2)) {
80 pDefaultFwFileName = default_prod_fw;
81 if (!GetNxpConfigStrValue(NAME_NXP_UWB_PROD_FW_FILENAME, configured_fw_name, fw_max_len)) {
82 ALOGD("Invalid Prod Fw name keeping the default name: %s", pDefaultFwFileName);
83 strncat(default_fw_path, pDefaultFwFileName, maxSrcLen);
84 } else{
85 ALOGD("configured_fw_name : %s", configured_fw_name);
86 strncat(default_fw_path, configured_fw_name, maxSrcLen);
87 }
88 } else if (deviceLcInfo == PHHBCI_HELIOS_DEV_KEY) {
89 pDefaultFwFileName = default_dev_fw;
90 if (!GetNxpConfigStrValue(NAME_NXP_UWB_DEV_FW_FILENAME, configured_fw_name, fw_max_len)) {
91 ALOGD("Invalid Dev Fw name keeping the default name: %s", pDefaultFwFileName);
92 strncat(default_fw_path, pDefaultFwFileName, maxSrcLen);
93 } else{
94 ALOGD("configured_fw_name : %s", configured_fw_name);
95 strncat(default_fw_path, configured_fw_name, maxSrcLen);
96 }
97 } else {
98 ALOGD("Invalid DeviceLCInfo : 0x%x\n", deviceLcInfo);
99 return 1;
100 }
101
102 ALOGD("Referring FW path..........: %s", default_fw_path);
103 if (gImg && (NULL == (gOpts.fImg = fopen(default_fw_path, "rb")))) {
104 ALOGD("ERROR: Cannot open %s file for reading!\n", gOpts.imgFile);
105 return 1;
106 } else {
107 ALOGD("FW FILE OPEN SUCCESS....\n");
108 gImg = true;
109 // gOpts.capture = Capture_Apdu_With_Dummy_Miso;
110 }
111
112 if (Capture_Off != gOpts.capture) {
113 ALOGD("Not Capture_Off.....\n");
114 if (NULL == (gOpts.fMosi = fopen(gOpts.mosiFile, "wb"))) {
115 ALOGD("ERROR: Cannot open %s file for writing!\n", gOpts.mosiFile);
116 return 1;
117 }
118
119 if (NULL == (gOpts.fMiso = fopen(gOpts.misoFile, "wb"))) {
120 ALOGD("ERROR: Cannot open %s file for writing!\n", gOpts.misoFile);
121 return 1;
122 }
123
124 if (Capture_Apdu_With_Dummy_Miso == gOpts.capture) {
125 memset(gDummyMiso, 0xEE, sizeof(gDummyMiso));
126 }
127 }
128
129 return 0;
130 }
131
cleanup(void)132 static void cleanup(void)
133 {
134 ioctl((intptr_t)tPalConfig.pDevHandle, SRXXX_SET_FWD, 0);
135 if(configured_fw_name !=NULL){
136 free(configured_fw_name);
137 memset(default_fw_path, '\0', sizeof(char)*256);
138 strcpy(default_fw_path, "/vendor/firmware/uwb/");
139 }
140 if (NULL != gOpts.fImg)
141 {
142 fclose(gOpts.fImg);
143 }
144
145 if (NULL != gOpts.fMosi)
146 {
147 fclose(gOpts.fMosi);
148 }
149
150 if (NULL != gOpts.fMiso)
151 {
152 fclose(gOpts.fMiso);
153 }
154 }
phHbci_GetStatus(void)155 phHbci_Status_t phHbci_GetStatus(void)
156 {
157 ALOGD("phHbci_GetStatus Enter\n");
158 phHbci_Status_t ret = phHbci_Failure;
159
160 gphHbci_MosiApdu.len = 0;
161
162 if (phHbci_Success != (ret = phHbci_PutApdu((uint8_t *)&gphHbci_MosiApdu, PHHBCI_LEN_HDR)))
163 {
164 return ret;
165 }
166 if (phHbci_Success != (ret = phHbci_GetApdu((uint8_t *)&gphHbci_MisoApdu, PHHBCI_LEN_HDR)))
167 {
168 return ret;
169 }
170
171 return phHbci_Success;
172 }
173
phHbci_GeneralStatus(phHbci_General_Command_t mode)174 phHbci_Status_t phHbci_GeneralStatus(phHbci_General_Command_t mode)
175 {
176 ALOGD("phHbci_GeneralStatus Enter\n");
177 switch (gphHbci_MisoApdu.cls)
178 {
179 case phHbci_Class_General | phHbci_SubClass_Answer:
180 switch (gphHbci_MisoApdu.ins)
181 {
182 case phHbci_General_Ans_HBCI_Ready:
183 if (!mode)
184 {
185 return phHbci_Success;
186 }
187
188 ALOGD("ERROR: Unexpected General Status 0x%02x In Mode 0x%02x\n", gphHbci_MisoApdu.ins, mode);
189 break;
190
191 case phHbci_General_Ans_Mode_Patch_ROM_Ready:
192 if (phHbci_General_Cmd_Mode_Patch_ROM == mode)
193 {
194 return phHbci_Success;
195 }
196
197 ALOGD("ERROR: Unexpected General Status 0x%02x In Mode 0x%02x\n", gphHbci_MisoApdu.ins, mode);
198 break;
199
200 case phHbci_General_Ans_Mode_HIF_Image_Ready:
201 if (phHbci_General_Cmd_Mode_HIF_Image == mode)
202 {
203 return phHbci_Success;
204 }
205
206 ALOGD("ERROR: Unexpected General Status 0x%02x In Mode 0x%02x\n", gphHbci_MisoApdu.ins, mode);
207 break;
208
209 case phHbci_General_Ans_HBCI_Fail:
210 case phHbci_General_Ans_Boot_Autoload_Fail:
211 case phHbci_General_Ans_Boot_GPIOConf_CRC_Fail:
212 case phHbci_General_Ans_Boot_TRIM_CRC_Fail:
213 case phHbci_General_Ans_Boot_GPIOTRIM_CRC_Fail:
214 ALOGD("ERROR: HBCI Interface Failed With 0x%02x\n", gphHbci_MisoApdu.ins);
215 break;
216
217 case phHbci_General_Ans_Mode_Patch_ROM_Fail:
218 ALOGD("ERROR: Patch ROM Mode Failed!\n");
219 break;
220
221 case phHbci_General_Ans_Mode_HIF_Image_Fail:
222 ALOGD("ERROR: HIF Image Mode Failed!\n");
223 break;
224
225 default:
226 ALOGD("ERROR: Unknown General Status 0x%02x\n", gphHbci_MisoApdu.ins);
227 break;
228 }
229 break;
230
231 case phHbci_Class_General | phHbci_SubClass_Ack:
232 switch (gphHbci_MisoApdu.ins)
233 {
234 case phHbci_Invlaid_Class:
235 ALOGD ("ERROR: Invalid Class Error From Slave!\n");
236 break;
237
238 case phHbci_Invalid_Instruction:
239 ALOGD ("ERROR: Invalid Instruction Error From Slave!\n");
240 break;
241
242 default:
243 ALOGD("ERROR: Unexpected Instruction From Slave 0x%02x\n", gphHbci_MisoApdu.ins);
244 break;
245 }
246 break;
247
248 default:
249 ALOGD("ERROR: Unknown General Class 0x%02x\n", gphHbci_MisoApdu.cls);
250 break;
251 }
252
253 return phHbci_Failure;
254 }
255
phHbci_QueryInfo(uint8_t * pInfo,uint32_t * pInfoSz,uint32_t maxSz,bool matchMaxSz)256 phHbci_Status_t phHbci_QueryInfo(uint8_t *pInfo, uint32_t *pInfoSz, uint32_t maxSz, bool matchMaxSz)
257 {
258 ALOGD("phHbci_QueryInfo Enter\n");
259 uint8_t expCls, expIns;
260 uint16_t lrc, dataSz, payloadSz, segment;
261 phHbci_Status_t ret = phHbci_Failure;
262
263 if (maxSz > PHHBCI_MAX_LEN_DATA_MISO)
264 {
265 ALOGD("ERROR: Info Size Cannot Be Greater Than %u Bytes!\n", PHHBCI_MAX_LEN_DATA_MISO);
266 return phHbci_Failure;
267 }
268
269 expCls = (gphHbci_MosiApdu.cls & (uint8_t)PHHBCI_CLASS_MASK) | phHbci_SubClass_Answer;
270 expIns = gphHbci_MosiApdu.ins;
271
272 gphHbci_MosiApdu.len = 0;
273
274 if (phHbci_Success != (ret = phHbci_PutApdu((uint8_t *)&gphHbci_MosiApdu, PHHBCI_LEN_HDR)))
275 {
276 return ret;
277 }
278
279 if (phHbci_Success != (ret = phHbci_GetApdu((uint8_t *)&gphHbci_MisoApdu, PHHBCI_LEN_HDR)))
280 {
281 return ret;
282 }
283
284 payloadSz = gphHbci_MisoApdu.len;
285 segment = payloadSz & PHHBCI_APDU_SEG_FLAG;
286
287 if (!segment)
288 {
289 lrc = payloadSz ? PHHBCI_LEN_LRC : 0;
290 dataSz = payloadSz - lrc;
291
292 if (!dataSz)
293 {
294 ALOGD("ERROR: No Info From Slave!\n");
295 return phHbci_Failure;
296 }
297 }
298
299 gphHbci_MosiApdu.cls = (uint8_t)(phHbci_Class_General | phHbci_SubClass_Ack);
300 gphHbci_MosiApdu.ins = (uint8_t)phHbci_Valid_APDU;
301
302 if (gphHbci_MisoApdu.cls != expCls)
303 {
304 ALOGD("ERROR: Invalid Class - Exp 0x%02x, Got 0x%02x\n", expCls, gphHbci_MisoApdu.cls);
305 gphHbci_MosiApdu.ins = phHbci_Invlaid_Class;
306 }
307 else if (gphHbci_MisoApdu.ins != expIns)
308 {
309 ALOGD("ERROR: Invalid Instruction - Exp 0x%02x, Got 0x%02x\n", expIns, gphHbci_MisoApdu.ins);
310 gphHbci_MosiApdu.ins = phHbci_Invalid_Instruction;
311 }
312 else if (segment)
313 {
314 ALOGD("ERROR: Invalid Payload Length!\n");
315 gphHbci_MosiApdu.ins = phHbci_Invalid_Segment_Length;
316 }
317 else if (dataSz > maxSz)
318 {
319 ALOGD("ERROR: Total Size (%u) Greater Than Max. Size (%u)!\n", dataSz, maxSz);
320 gphHbci_MosiApdu.ins = phHbci_Invalid_Segment_Length;
321 }
322 else if (matchMaxSz && (dataSz != maxSz))
323 {
324 ALOGD("ERROR: Total Size (%u) Not Equal To Expected Size (%u)!\n", dataSz, maxSz);
325 gphHbci_MosiApdu.ins = phHbci_Invalid_Segment_Length;
326 }
327
328 if (phHbci_Success != (ret = phHbci_PutApdu((uint8_t *)&gphHbci_MosiApdu, PHHBCI_LEN_HDR)))
329 {
330 return ret;
331 }
332
333 if (gphHbci_MosiApdu.ins & PHHBCI_ERROR_STATUS_MASK)
334 {
335 return phHbci_Failure;
336 }
337
338 if (phHbci_Success != (ret = phHbci_GetApdu((uint8_t *)gphHbci_MisoApdu.payload, payloadSz)))
339 {
340 return ret;
341 }
342
343 if (gphHbci_MisoApdu.payload[dataSz] != phHbci_CalcLrc((uint8_t *)&gphHbci_MisoApdu, PHHBCI_LEN_HDR + dataSz))
344 {
345 ALOGD("ERROR: Invalid LRC!\n");
346 return phHbci_Failure;
347 }
348
349 memcpy(&pInfo[*pInfoSz], gphHbci_MisoApdu.payload, dataSz);
350 *pInfoSz += dataSz;
351
352 return phHbci_Success;
353 }
354
phHbci_GetGeneralInfo(uint8_t * pInfo,uint32_t * pInfoSz)355 phHbci_Status_t phHbci_GetGeneralInfo(uint8_t *pInfo, uint32_t *pInfoSz)
356 {
357 ALOGD("phHbci_GetGeneralInfo\n");
358 if (gphHbci_MosiApdu.cls != (uint8_t)(phHbci_Class_General | phHbci_SubClass_Query))
359 {
360 ALOGD("ERROR: Invalid General Info Class = 0x%02x\n", gphHbci_MosiApdu.cls);
361 return phHbci_Failure;
362 }
363
364 switch (gphHbci_MosiApdu.ins)
365 {
366 case phHbci_General_Qry_Chip_ID:
367 return phHbci_QueryInfo(pInfo, pInfoSz, PHHBCI_HELIOS_CHIP_ID_SZ, TRUE);
368
369 case phHbci_General_Qry_Helios_ID:
370 return phHbci_QueryInfo(pInfo, pInfoSz, PHHBCI_HELIOS_ID_SZ, TRUE);
371
372 //case phHbci_General_Qry_CA_Root_Pub_Key:
373 // return phHbci_QueryInfo(pInfo, pInfoSz, PHHBCI_HELIOS_CA_ROOT_PUB_KEY_SZ, TRUE);
374
375 case phHbci_General_Qry_NXP_Pub_Key:
376 return phHbci_QueryInfo(pInfo, pInfoSz, PHHBCI_HELIOS_NXP_PUB_KEY_SZ, TRUE);
377
378 case phHbci_General_Qry_ROM_Version:
379 return phHbci_QueryInfo(pInfo, pInfoSz, PHHBCI_HELIOS_ROM_VERSION_SZ, TRUE);
380
381 case phHbci_General_Qry_OTP_AutoLoad_Info:
382 return phHbci_QueryInfo(pInfo, pInfoSz, PHHBCI_HELIOS_OTP_AUTOLOAD_INFO_SZ, TRUE);
383 default:
384 ALOGD("ERROR: Undefined General Query = 0x%02x\n", gphHbci_MosiApdu.ins);
385 return phHbci_Failure;
386 }
387
388 return phHbci_Success;
389 }
390
phHbci_GetInfo(uint8_t * pInfo,uint32_t * pInfoSz)391 phHbci_Status_t phHbci_GetInfo(uint8_t *pInfo, uint32_t *pInfoSz)
392 {
393 ALOGD("phHbci_GetInfo Enter\n");
394 switch (gphHbci_MosiApdu.cls)
395 {
396 case phHbci_Class_General | phHbci_SubClass_Query:
397 return phHbci_GetGeneralInfo(pInfo, pInfoSz);
398 break;
399
400 default:
401 ALOGD("ERROR: No Info Defined For Class = 0x%02x\n", gphHbci_MosiApdu.cls);
402 return phHbci_Failure;
403 }
404
405 return phHbci_Success;
406 }
407
phHbci_PutCommand(uint8_t * pImg,uint32_t imgSz)408 phHbci_Status_t phHbci_PutCommand(uint8_t *pImg, uint32_t imgSz)
409 {
410 ALOGD("phHbci_PutCommand Enter\n");
411 uint8_t ackCls, ackIns;
412 uint16_t lrc, dataSz, payloadSz;
413 phHbci_Status_t ret = phHbci_Failure;
414
415 ackCls = (uint8_t)(phHbci_Class_General | phHbci_SubClass_Ack);
416 ackIns = (uint8_t)phHbci_Valid_APDU;
417
418 do
419 {
420 //ALOGD("fwd while loop...imgSz: %d\n",imgSz);
421 if (imgSz > PHHBCI_MAX_LEN_DATA_MOSI)
422 {
423 dataSz = PHHBCI_MAX_LEN_DATA_MOSI;
424 payloadSz = PHHBCI_APDU_SEG_FLAG;
425 }
426 else
427 {
428 lrc = imgSz ? PHHBCI_LEN_LRC : 0;
429 dataSz = imgSz;
430 payloadSz = dataSz + lrc;
431 }
432 //ALOGD("dataSz : %d\n",dataSz);
433 gphHbci_MosiApdu.len = payloadSz;
434 usleep(1);
435
436 if (phHbci_Success != (ret = phHbci_PutApdu((uint8_t *)&gphHbci_MosiApdu, PHHBCI_LEN_HDR)))
437 {
438 return ret;
439 }
440 usleep(1);
441 if (phHbci_Success != (ret = phHbci_GetApdu((uint8_t *)&gphHbci_MisoApdu, PHHBCI_LEN_HDR)))
442 {
443 return ret;
444 }
445
446 if ((gphHbci_MisoApdu.cls != ackCls) || (gphHbci_MisoApdu.ins != ackIns))
447 {
448 ALOGD("ERROR: NACK (CLS = 0x%02x, INS = 0x%02x)\n", gphHbci_MisoApdu.cls, gphHbci_MisoApdu.ins);
449 return phHbci_Failure;
450 }
451
452 if (dataSz)
453 {
454 //ALOGD("dataSz is not zero......");
455 memcpy(gphHbci_MosiApdu.payload, pImg, dataSz);
456 gphHbci_MosiApdu.payload[dataSz] = phHbci_CalcLrc((uint8_t *)&gphHbci_MosiApdu, PHHBCI_LEN_HDR + dataSz);
457
458 pImg += dataSz;
459 imgSz -= dataSz;
460 payloadSz = dataSz + PHHBCI_LEN_LRC;
461 if(chip_id == PHHBCI_FW_B2_VERSION)
462 {
463 usleep(250);
464 }
465
466 if (phHbci_Success != (ret = phHbci_PutApdu((uint8_t *)gphHbci_MosiApdu.payload, payloadSz)))
467 {
468 return ret;
469 }
470
471 if (phHbci_Success != (ret = phHbci_GetApdu((uint8_t *)&gphHbci_MisoApdu, PHHBCI_LEN_HDR)))
472 {
473 return ret;
474 }
475
476 if ((gphHbci_MisoApdu.cls != ackCls) || (gphHbci_MisoApdu.ins != ackIns))
477 {
478 ALOGD("ERROR: NACK (CLS = 0x%02x, INS = 0x%02x)\n", gphHbci_MisoApdu.cls, gphHbci_MisoApdu.ins);
479 return phHbci_Failure;
480 }
481 }
482 }
483 while (imgSz);
484
485 return phHbci_Success;
486 }
487
phHbci_MasterPatchROM(uint8_t * pImg,uint32_t imgSz)488 static phHbci_Status_t phHbci_MasterPatchROM(uint8_t *pImg, uint32_t imgSz)
489 {
490 ALOGD("phHbci_MasterPatchROM enter");
491 phHbci_Status_t ret = phHbci_Failure;
492
493 gphHbci_MosiApdu.cls = (uint8_t)(phHbci_Class_General | phHbci_SubClass_Query);
494 gphHbci_MosiApdu.ins = (uint8_t)phHbci_General_Qry_Status;
495
496 while (1)
497 {
498 if (phHbci_Success != (ret = phHbci_GetStatus()))
499 {
500 return ret;
501 }
502
503 switch (gphHbci_MisoApdu.cls)
504 {
505 case phHbci_Class_General | phHbci_SubClass_Answer:
506 case phHbci_Class_General | phHbci_SubClass_Ack:
507 if (phHbci_Success != (ret = phHbci_GeneralStatus(phHbci_General_Cmd_Mode_Patch_ROM)))
508 {
509 return ret;
510 }
511
512 gphHbci_MosiApdu.cls = (uint8_t)(phHbci_Class_Patch_ROM | phHbci_SubClass_Command);
513 gphHbci_MosiApdu.ins = (uint8_t)phHbci_Patch_ROM_Cmd_Download_Patch;
514
515 /* Reset GPIO event flag */
516 //cppResetGPIOEvent();
517
518 if (phHbci_Success != (ret = phHbci_PutCommand(pImg, imgSz)))
519 {
520 return ret;
521 }
522
523 /* Wait for GPIO event */
524 /*if (0 > cppWaitForGPIOEvent(PHHBCI_GPIO_TIMEOUT_MS))
525 {
526 ALOGD("ERROR: GPIO notification timeout!\n");
527 }*/
528
529 gphHbci_MosiApdu.cls = (uint8_t)(phHbci_Class_Patch_ROM | phHbci_SubClass_Query);
530 gphHbci_MosiApdu.ins = (uint8_t)phHbci_Patch_ROM_Qry_Patch_Status;
531 break;
532
533 case phHbci_Class_Patch_ROM | phHbci_SubClass_Answer:
534 switch (gphHbci_MisoApdu.ins)
535 {
536 case phHbci_Patch_ROM_Ans_Patch_Success:
537 ALOGD("Patch ROM Transfer Complete.\n");
538 ret = phHbci_Success;
539 break;
540
541 case phHbci_Patch_ROM_Ans_File_Too_Large:
542 case phHbci_Patch_ROM_Ans_Invalid_Patch_File_Marker:
543 case phHbci_Patch_ROM_Ans_Too_Many_Patch_Table_Entries:
544 case phHbci_Patch_ROM_Ans_Invalid_Patch_Code_Size:
545 case phHbci_Patch_ROM_Ans_Invalid_Global_Patch_Marker:
546 case phHbci_Patch_ROM_Ans_Invalid_Signature_Size:
547 case phHbci_Patch_ROM_Ans_Invalid_Signature:
548 ALOGD("EROOR: Patch ROM Transfer Failed With 0x%02x!\n", gphHbci_MisoApdu.ins);
549 ret = phHbci_Failure;
550 break;
551
552 default:
553 ALOGD("ERROR: Unknown Patch ROM Status 0x%02x\n", gphHbci_MisoApdu.ins);
554 ret = phHbci_Failure;
555 break;
556 }
557 return ret;
558
559 default:
560 ALOGD("ERROR: Unknown Class 0x%02x\n", gphHbci_MisoApdu.cls);
561 return phHbci_Failure;
562 }
563 }
564
565 return phHbci_Success;
566 }
567
phHbci_MasterHIFImage(uint8_t * pImg,uint32_t imgSz)568 static phHbci_Status_t phHbci_MasterHIFImage(uint8_t *pImg, uint32_t imgSz)
569 {
570 ALOGD("phHbci_MasterHIFImage enter");
571 phHbci_Status_t ret = phHbci_Failure;
572
573 gphHbci_MosiApdu.cls = (uint8_t)(phHbci_Class_General | phHbci_SubClass_Query);
574 gphHbci_MosiApdu.ins = (uint8_t)phHbci_General_Qry_Status;
575
576 while (1)
577 {
578 if (phHbci_Success != (ret = phHbci_GetStatus()))
579 {
580 return ret;
581 }
582
583 switch (gphHbci_MisoApdu.cls)
584 {
585 case phHbci_Class_General | phHbci_SubClass_Answer:
586 case phHbci_Class_General | phHbci_SubClass_Ack:
587 if (phHbci_Success != (ret = phHbci_GeneralStatus(phHbci_General_Cmd_Mode_HIF_Image)))
588 {
589 return ret;
590 }
591
592 gphHbci_MosiApdu.cls = (uint8_t)(phHbci_Class_HIF_Image | phHbci_SubClass_Command);
593 gphHbci_MosiApdu.ins = (uint8_t)phHbci_HIF_Image_Cmd_Download_Image;
594
595 /* Reset GPIO event flag */
596 // cppResetGPIOEvent();
597
598 if (phHbci_Success != (ret = phHbci_PutCommand(pImg, imgSz)))
599 {
600 return ret;
601 }
602
603 /* Wait for GPIO event */
604 /* if (0 > cppWaitForGPIOEvent(PHHBCI_GPIO_TIMEOUT_MS))
605 {
606 ALOGD("ERROR: GPIO notification timeout!\n");
607 }*/
608 usleep(100000);
609
610 gphHbci_MosiApdu.cls = (uint8_t)(phHbci_Class_HIF_Image | phHbci_SubClass_Query);
611 gphHbci_MosiApdu.ins = (uint8_t)phHbci_HIF_Image_Qry_Image_Status;
612 break;
613
614 case phHbci_Class_HIF_Image | phHbci_SubClass_Answer:
615 switch (gphHbci_MisoApdu.ins)
616 {
617 case phHbci_HIF_Image_Ans_Image_Success:
618 ALOGD("HIF Image Transfer Complete.\n");
619 /*Check FW download throughput measurement*/
620 //ioctl((intptr_t)tPalConfig.pDevHandle, SRXXX_GET_THROUGHPUT, 0);
621 return phHbci_Success;
622
623 case phHbci_HIF_Image_Ans_Header_Too_Large:
624 case phHbci_HIF_Image_Ans_Header_Parse_Error:
625 case phHbci_HIF_Image_Ans_Invalid_Cipher_Type_Crypto:
626 case phHbci_HIF_Image_Ans_Invalid_Cipher_Type_Hash:
627 case phHbci_HIF_Image_Ans_Invalid_Cipher_Type_Curve:
628 case phHbci_HIF_Image_Ans_Invalid_ECC_Key_Length:
629 case phHbci_HIF_Image_Ans_Invalid_Payload_Description:
630 case phHbci_HIF_Image_Ans_Invalid_Firmware_Version:
631 case phHbci_HIF_Image_Ans_Invalid_ECID_Mask:
632 case phHbci_HIF_Image_Ans_Invalid_ECID_Value:
633 case phHbci_HIF_Image_Ans_Invalid_Encrypted_Payload_Hash:
634 case phHbci_HIF_Image_Ans_Invalid_Header_Signature:
635 case phHbci_HIF_Image_Ans_Install_Settings_Too_Large:
636 case phHbci_HIF_Image_Ans_Install_Settings_Parse_Error:
637 case phHbci_HIF_Image_Ans_Payload_Too_Large:
638 case phHbci_HIF_Image_Ans_Quickboot_Settings_Parse_Error:
639 case phHbci_HIF_Image_Ans_Invalid_Static_Hash:
640 case phHbci_HIF_Image_Ans_Invalid_Dynamic_Hash:
641 case phHbci_HIF_Image_Ans_Execution_Settings_Parse_Error:
642 case phHbci_HIF_Image_Ans_Key_Read_Error:
643 ALOGD("EROOR: HIF Image Transfer Failed With 0x%02x!\n", gphHbci_MisoApdu.ins);
644 return phHbci_Failure;
645
646 default:
647 ALOGD("ERROR: Unknown HIF Status 0x%02x\n", gphHbci_MisoApdu.ins);
648 return phHbci_Failure;
649 }
650 break;
651
652 default:
653 ALOGD("ERROR: Unknown Class 0x%02x\n", gphHbci_MisoApdu.cls);
654 return phHbci_Failure;
655 }
656 }
657
658 return phHbci_Success;
659 }
660
661 /*********************************************************************************************************************/
662 /* GLOBAL FUNCTIONS */
663 /*********************************************************************************************************************/
phHbci_Master(phHbci_General_Command_t mode,uint8_t * pImg,uint32_t imgSz)664 phHbci_Status_t phHbci_Master(phHbci_General_Command_t mode, uint8_t *pImg, uint32_t imgSz)
665 {
666 ALOGD("phHbci_Master Enter\n");
667 // uint8_t info[PHHBCI_MAX_LEN_DATA_MISO];
668 // uint32_t infoSz = 0;
669 phHbci_Status_t ret = phHbci_Failure;
670
671 gphHbci_MosiApdu.cls = (uint8_t)(phHbci_Class_General | phHbci_SubClass_Query);
672 gphHbci_MosiApdu.ins = (uint8_t)phHbci_General_Qry_Status;
673
674 if (phHbci_Success != (ret = phHbci_GetStatus()))
675 {
676 return ret;
677 }
678
679 if (phHbci_Success != (ret = phHbci_GeneralStatus((phHbci_General_Command_t)0)))
680 {
681 return ret;
682 }
683
684 gphHbci_MosiApdu.cls = (uint8_t)(phHbci_Class_General | phHbci_SubClass_Command);
685 gphHbci_MosiApdu.ins = (uint8_t)mode;
686 ALOGD("STARTING FW DOWNLOAD.....\n");
687 if (phHbci_Success != (ret = phHbci_PutCommand(pImg, 0)))
688 {
689 return ret;
690 }
691
692 switch (mode)
693 {
694 case phHbci_General_Cmd_Mode_Patch_ROM:
695 return phHbci_MasterPatchROM(pImg, imgSz);
696
697 case phHbci_General_Cmd_Mode_HIF_Image:
698 return phHbci_MasterHIFImage(pImg, imgSz);
699
700 default:
701 ALOGD("ERROR: Undefined mode 0x%02x\n", mode);
702 break;
703 }
704
705 return phHbci_Failure;
706 }
707
708 /*********************************************************************************************************************/
709 /* GLOBAL FUNCTIONS */
710 /*********************************************************************************************************************/
phHbci_CalcLrc(uint8_t * pBuf,uint16_t bufSz)711 uint8_t phHbci_CalcLrc(uint8_t *pBuf, uint16_t bufSz)
712 {
713 //ALOGD("phHbci_CalcLrc....\n");
714 uint8_t lrc = 0;
715 uint16_t i;
716
717 if (!pBuf || !bufSz)
718 return lrc;
719
720 /* ISO 1155:1978 Information processing -- Use of longitudinal parity to detect errors in information messages */
721 for (i = 0; i < bufSz; i++)
722 {
723 lrc += *pBuf++;
724 }
725
726 lrc ^= 0xFF;
727 lrc += 1;
728
729 return lrc;
730 }
731 /*********************************************************************************************************************/
732 /* GLOBAL FUNCTIONS */
733 /*********************************************************************************************************************/
phHbci_GetApdu(uint8_t * pApdu,uint16_t sz)734 phHbci_Status_t phHbci_GetApdu(uint8_t *pApdu, uint16_t sz)
735 {
736 // ALOGD("phHbci_GetApdu Enter\n");
737 uint16_t ret;
738 int ret_Read;
739 if (sz == 0 || sz > PHHBCI_MAX_LEN_PAYLOAD_MISO) {
740 ALOGD("ERROR: phHbci_GetApdu data len is 0 or greater than max palyload length supported\n");
741 return phHbci_Failure;
742 }
743 ret_Read = read((intptr_t)tPalConfig.pDevHandle, (void*)pApdu, (sz));
744 if (ret_Read < 0)
745 {
746 ALOGD("ERROR: Get APDU %u bytes failed!\n", sz);
747 return phHbci_Failure;
748 }
749
750 if(is_fw_download_log_enabled == 0x01)
751 phNxpUciHal_print_packet("RECV",pApdu,ret_Read);
752
753 switch (gOpts.capture)
754 {
755 case Capture_Apdu_With_Dummy_Miso:
756 if (sz != (ret = fwrite(gDummyMiso, sizeof(uint8_t), sz, gOpts.fMosi)))
757 {
758 ALOGD("ERROR: %s dummy write returned %d, expected %d\n", gOpts.mosiFile, ret, sz);
759 }
760 if (sz != (ret = fwrite(pApdu, sizeof(uint8_t), sz, gOpts.fMiso)))
761 {
762 ALOGD("ERROR: %s write returned %d, expected %d\n", gOpts.misoFile, ret, sz);
763 }
764 break;
765 case Capture_Apdu:
766 if (sz != (ret = fwrite(pApdu, sizeof(uint8_t), sz, gOpts.fMiso)))
767 {
768 ALOGD("ERROR: %s write returned %d, expected %d\n", gOpts.misoFile, ret, sz);
769 }
770 break;
771
772 case Capture_Off:
773 default:
774 break;
775 }
776 //ALOGD("Rx --> 0X%x 0X%x 0X%x 0X%x.\n", pApdu[0], pApdu[1], pApdu[2],pApdu[3]);
777 return phHbci_Success;
778 }
779
phHbci_PutApdu(uint8_t * pApdu,uint16_t sz)780 phHbci_Status_t phHbci_PutApdu(uint8_t *pApdu, uint16_t sz)
781 {
782 // ALOGD("phHbci_PutApdu Enter\n");
783 int ret;
784 int numWrote = 0;
785 if(is_fw_download_log_enabled == 0x01)
786 phNxpUciHal_print_packet("SEND",pApdu,sz);
787
788 ret = write((intptr_t)tPalConfig.pDevHandle, pApdu,sz);
789 if (ret > 0) {
790 numWrote += ret;
791 } else if (ret == 0) {
792 ALOGD("_spi_write() EOF");
793 return (phHbci_Status_t)1;
794 } else {
795 ALOGD("_spi_write() errno : %x", ret);
796 return (phHbci_Status_t)1;
797 }
798 switch (gOpts.capture)
799 {
800 case Capture_Apdu_With_Dummy_Miso:
801 case Capture_Apdu:
802 ALOGD("Write dummy apdu......\n");
803 ret = write((intptr_t)tPalConfig.pDevHandle, pApdu,sz);
804 if (ret > 0) {
805 numWrote += ret;
806 } else if (ret == 0) {
807 ALOGD("_spi_write() EOF");
808 return (phHbci_Status_t)1;
809 } else {
810 ALOGD("_spi_write() errno : %x", ret);
811 return (phHbci_Status_t)1;
812 }
813 /*if (sz != (ret = fwrite(pApdu, sizeof(uint8_t), sz, gOpts.fMosi)))
814 {
815 ALOGD("ERROR: %s write returned %d, expected %d\n", gOpts.mosiFile, ret, sz);
816 }*/
817 break;
818
819 case Capture_Off:
820 default:
821 break;
822 }
823 //ALOGD("Tx-->0X%x 0X%x 0X%x 0X%x......\n", pApdu[0], pApdu[1], pApdu[2],pApdu[3]);
824 return phHbci_Success;
825 }
826
phHbci_GetChipIdInfo()827 phHbci_Status_t phHbci_GetChipIdInfo(){
828 phHbci_Status_t ret = phHbci_Failure;
829 uint8_t FwdExtndLenIndication = 0, totalBtyesToReadMsb = 0;
830 uint16_t totalBtyesToRead = 0;
831 uint8_t hbciData[PHHBCI_MAX_LEN_PAYLOAD_MISO];
832
833 gphHbci_MosiApdu.cls = (uint8_t)(phHbci_Class_General | phHbci_SubClass_Query);
834 gphHbci_MosiApdu.ins = (uint8_t)phHbci_General_Qry_Chip_ID;
835
836 gphHbci_MosiApdu.len = 0;
837
838 if (phHbci_Success != (ret = phHbci_PutApdu((uint8_t *)&gphHbci_MosiApdu, PHHBCI_LEN_HDR)))
839 {
840 return ret;
841 }
842 usleep(1);
843 if (phHbci_Success != (ret = phHbci_GetApdu((uint8_t *)&hbciData[0], PHHBCI_LEN_HDR)))
844 {
845 return ret;
846 }
847 FwdExtndLenIndication = ((hbciData[PHHBCI_MODE_LEN_MSB_OFFSET] & 0xF0) >> 4);
848 totalBtyesToReadMsb = (hbciData[PHHBCI_MODE_LEN_MSB_OFFSET] & 0x0F);
849 totalBtyesToRead = (hbciData[PHHBCI_MODE_LEN_LSB_OFFSET] | (totalBtyesToReadMsb << 8));
850
851 if (totalBtyesToRead == 0) {
852 ALOGD("ERROR: hbci data len is 0\n");
853 return phHbci_Failure;
854 }
855 gphHbci_MosiApdu.cls = (uint8_t)phHbci_SubClass_Ack;
856 gphHbci_MosiApdu.ins = (uint8_t)phHbci_SubClass_Query;
857 gphHbci_MosiApdu.len = 0;
858
859 if (phHbci_Success != (ret = phHbci_PutApdu((uint8_t *)&gphHbci_MosiApdu, PHHBCI_LEN_HDR)))
860 {
861 return ret;
862 }
863 usleep(1);
864
865 if (phHbci_Success != (ret = phHbci_GetApdu((uint8_t *)&hbciData[0], totalBtyesToRead)))
866 {
867 return ret;
868 }
869 chip_id = hbciData[PHHBCI_MODE_CHIP_ID_OFFSET];
870 ALOGD("Recived ChipId = 0x%02x\n", chip_id);
871
872 return phHbci_Success;
873 }
874
875 /******************************************************************************
876 * Function phHbci_GetDeviceLcInfo
877 *
878 * Description This function is called to get the OTP Autoload Info
879 * Returns return 0 on success and -1
880 *
881 ******************************************************************************/
phHbci_GetDeviceLcInfo()882 phHbci_Status_t phHbci_GetDeviceLcInfo(){
883 phHbci_Status_t ret = phHbci_Failure;
884 uint8_t FwdExtndLenIndication = 0,totalBtyesToReadMsb = 0;
885 uint16_t totalBtyesToRead = 0;
886 uint8_t hbciData[PHHBCI_MAX_LEN_PAYLOAD_MISO];
887
888 gphHbci_MosiApdu.cls = (uint8_t)(phHbci_Class_General | phHbci_SubClass_Query);
889 gphHbci_MosiApdu.ins = (uint8_t)phHbci_General_Qry_OTP_AutoLoad_Info;
890
891 gphHbci_MosiApdu.len = 0;
892
893 if (phHbci_Success != (ret = phHbci_PutApdu((uint8_t *)&gphHbci_MosiApdu, PHHBCI_LEN_HDR)))
894 {
895 return ret;
896 }
897 usleep(1);
898 if (phHbci_Success != (ret = phHbci_GetApdu((uint8_t *)&hbciData[0], PHHBCI_LEN_HDR)))
899 {
900 return ret;
901 }
902
903 FwdExtndLenIndication = ((hbciData[PHHBCI_MODE_LEN_MSB_OFFSET] & 0xF0) >> 4);
904 totalBtyesToReadMsb = (hbciData[PHHBCI_MODE_LEN_MSB_OFFSET] & 0x0F);
905 totalBtyesToRead = (uint16_t)(hbciData[PHHBCI_MODE_LEN_LSB_OFFSET] | (totalBtyesToReadMsb << 8));
906
907 if (totalBtyesToRead == 0) {
908 ALOGD("ERROR: hbci data len is 0\n");
909 return phHbci_Failure;
910 }
911 gphHbci_MosiApdu.cls = (uint8_t)phHbci_SubClass_Ack;
912 gphHbci_MosiApdu.ins = (uint8_t)phHbci_SubClass_Query;
913 gphHbci_MosiApdu.len = 0;
914
915 if (phHbci_Success != (ret = phHbci_PutApdu((uint8_t *)&gphHbci_MosiApdu, PHHBCI_LEN_HDR)))
916 {
917 return ret;
918 }
919 usleep(1);
920 if (phHbci_Success != (ret = phHbci_GetApdu((uint8_t *)&hbciData[0], totalBtyesToRead)))
921 {
922 return ret;
923 }
924
925 deviceLcInfo = hbciData[PHHBCI_MODE_DEV_LIFE_CYCLE_INFO_OFFSET];
926 ALOGD("Recived devLifeCycleId = 0x%02x\n", deviceLcInfo);
927
928 return phHbci_Success;
929 }
930
931 /******************************************************************************
932 * Function phNxpUciHal_fw_download
933 *
934 * Description This function is called by jni when wired mode is
935 * performed.First SR100 driver will give the access
936 * permission whether wired mode is allowed or not
937 * arg (0):
938 * Returns return 0 on success and -1 on fail, On success
939 * update the acutual state of operation in arg pointer
940 *
941 ******************************************************************************/
phNxpUciHal_fw_download()942 int phNxpUciHal_fw_download() {
943 uint8_t *pImg = gphHbci_ImgHelios;
944 uint32_t imgSz=0, maxSz, err = 0;
945 unsigned long num = 0;
946 phHbci_General_Command_t cmd;
947 ALOGE("phNxpUciHal_fw_download enter and FW download started.....\n");
948 setOpts();
949
950
951 ioctl((intptr_t)tPalConfig.pDevHandle, SRXXX_SET_FWD, 1);
952 /* Always display chip id information */
953 is_fw_download_log_enabled = true;
954 if (phHbci_Success != phHbci_GetDeviceLcInfo())
955 {
956 ALOGD("phHbci_GetDeviceLcInfo Failure!\n");
957 return 1;
958 }
959
960 if (phHbci_Success != phHbci_GetChipIdInfo())
961 {
962 ALOGD("phHbci_GetChipIdInfo Failure!\n");
963 return 1;
964 }
965 is_fw_download_log_enabled = false;
966
967 if(GetNxpConfigNumValue(NAME_UWB_FW_DOWNLOAD_LOG, &num, sizeof(num))){
968 is_fw_download_log_enabled = (uint8_t)num;
969 ALOGD("NAME_UWB_FW_DOWNLOAD_LOG: 0x%02x\n",is_fw_download_log_enabled);
970 } else {
971 ALOGD("NAME_UWB_FW_DOWNLOAD_LOG: failed 0x%02x\n",is_fw_download_log_enabled);
972 }
973 if (init())
974 {
975 ALOGD("INIT Failed.....\n");
976 cleanup();
977 return 1;
978 }
979
980 switch (gOpts.mode)
981 {
982 case Mode_Patch_ROM:
983 cmd = phHbci_General_Cmd_Mode_Patch_ROM;
984 maxSz = PHHBCI_PATCHROM_MAX_IMAGE_SZ;
985 break;
986
987 case Mode_HIF_Image:
988 cmd = phHbci_General_Cmd_Mode_HIF_Image;
989 maxSz = PHHIF_MAX_IMAGE_SZ;
990 break;
991
992 default:
993 ALOGD("ERROR: Undefined Master Mode = %u\n", gOpts.mode);
994 return 1;
995 }
996 if (gImg)
997 {
998 if(gOpts.fImg == NULL) {
999 gOpts.fImg = fopen(default_fw_path, "rb");
1000 }
1001 if(gOpts.fImg == NULL) {
1002 ALOGD("Firmware file does not exist:");
1003 return phHbci_File_Not_found;
1004 }
1005 fseek(gOpts.fImg, 0, SEEK_END);
1006 imgSz = (uint32_t)ftell(gOpts.fImg);
1007 ALOGD("FWD file size ftell returns: %d\n",imgSz);
1008 if (!imgSz || (maxSz < imgSz))
1009 {
1010 ALOGD("ERROR: %s image size (%d) not supported!\n", gOpts.imgFile, imgSz);
1011 cleanup();
1012 return 1;
1013 }
1014
1015 rewind(gOpts.fImg);
1016 }
1017 ALOGD("FWD file size: %d\n",imgSz);
1018 if (!gImg || (imgSz == fread(pImg, sizeof(uint8_t), imgSz, gOpts.fImg)))
1019 {
1020 if(cmd == phHbci_General_Cmd_Mode_HIF_Image) {
1021 ALOGD("HIF Image mode.\n");
1022 }
1023 err = phHbci_Master(cmd, pImg, imgSz);
1024 if (phHbci_Success != err)
1025 {
1026 ALOGD("Failure!\n");
1027 err = 1;
1028 }
1029 }
1030 else
1031 {
1032 ALOGD("ERROR: Image read failed!\n");
1033 err = 1;
1034 }
1035
1036 cleanup();
1037 return err;
1038
1039 }
1040
setDeviceHandle(void * pDevHandle)1041 void setDeviceHandle(void* pDevHandle)
1042 {
1043 ALOGD("Set the device handle!\n");
1044
1045 if(pDevHandle == NULL) {
1046 ALOGD("device handle is NULL!\n");
1047 } else {
1048 tPalConfig.pDevHandle = (void*) ((intptr_t)pDevHandle);
1049 }
1050
1051 }
1052