• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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