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