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