blob: 67e15a889b326206fd7d16df75ed2e38e81a51bb [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001/*****************************************************************************
2* Copyright Statement:
3* --------------------
4* This software is protected by Copyright and the information contained
5* herein is confidential. The software may not be copied and the information
6* contained herein may not be used or disclosed except with the written
7* permission of MediaTek Inc. (C) 2018
8*
9* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
10* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
11* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
12* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
13* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
14* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
15* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
16* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
17* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
18* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
19* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
20* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
21*
22* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
23* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
24* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
25* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
26* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
27*
28* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
29* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
30* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
31* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
32* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
33*
34*****************************************************************************/
35
36/*******************************************************************************
37 * Filename:
38 * ---------
39 * mcf_util.c
40 *
41 * Project:
42 * --------
43 * UMOLYA
44 *
45 * Description:
46 * ------------
47 * MD Configuration Framework internal utility.
48 *
49 * Author:
50 * -------
51 * -------
52 *
53 *==============================================================================
54 * HISTORY
55 * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
56 *------------------------------------------------------------------------------
57 * removed!
58 *
59 * removed!
60 * removed!
61 * removed!
62 * removed!
63 *
64 * removed!
65 * removed!
66 * removed!
67 * removed!
68 *
69 * removed!
70 * removed!
71 * removed!
72 * removed!
73 *
74 * removed!
75 * removed!
76 * removed!
77 *
78 * removed!
79 * removed!
80 * removed!
81 *
82 * removed!
83 * removed!
84 * removed!
85 *
86 * removed!
87 * removed!
88 * removed!
89 *
90 * removed!
91 * removed!
92 *
93 * removed!
94 * removed!
95 * removed!
96 * removed!
97 *
98 * removed!
99 * removed!
100 * removed!
101 * removed!
102 *
103 * removed!
104 * removed!
105 * removed!
106 *
107 * removed!
108 * removed!
109 * removed!
110 *
111 * removed!
112 * removed!
113 * removed!
114 * removed!
115 *
116 * removed!
117 * removed!
118 * removed!
119 * removed!
120 * removed!
121 * removed!
122 *
123 * removed!
124 * removed!
125 * removed!
126 *
127 * removed!
128 * removed!
129 * removed!
130 *
131 * removed!
132 *
133 * removed!
134 * removed!
135 * removed!
136 * removed!
137 *
138 * removed!
139 * removed!
140 * removed!
141 *
142 * removed!
143 * removed!
144 * removed!
145 * removed!
146 *
147 * removed!
148 * removed!
149 * removed!
150 * removed!
151 * removed!
152 *
153 * removed!
154 * removed!
155 * removed!
156 *
157 * removed!
158 * removed!
159 * removed!
160 *
161 * removed!
162 * removed!
163 * removed!
164 *
165 * removed!
166 * removed!
167 * removed!
168 * removed!
169 *
170 * removed!
171 * removed!
172 * removed!
173 *
174 * removed!
175 * removed!
176 * removed!
177 *
178 * removed!
179 * removed!
180 * removed!
181 *
182 * removed!
183 * removed!
184 * removed!
185 *
186 * removed!
187 * removed!
188 * removed!
189 *
190 * removed!
191 * removed!
192 * removed!
193 *
194 * removed!
195 * removed!
196 * removed!
197 *
198 * removed!
199 * removed!
200 * removed!
201 * removed!
202 *
203 * removed!
204 * removed!
205 * removed!
206 *
207 * removed!
208 * removed!
209 *
210 * removed!
211 * removed!
212 * removed!
213 *
214 * removed!
215 * removed!
216 * removed!
217 *
218 * removed!
219 * removed!
220 * removed!
221 *
222 * removed!
223 * removed!
224 * removed!
225 *
226 * removed!
227 * removed!
228 * removed!
229 *
230 * removed!
231 * removed!
232 * removed!
233 *
234 * removed!
235 * removed!
236 * removed!
237 *
238 * removed!
239 * removed!
240 * removed!
241 *
242 * removed!
243 * removed!
244 * removed!
245 *
246 * removed!
247 * removed!
248 * removed!
249 *
250 * removed!
251 * removed!
252 * removed!
253 *
254 * removed!
255 * removed!
256 * removed!
257 *
258 * removed!
259 * removed!
260 * removed!
261 * removed!
262 *
263 * removed!
264 * removed!
265 * removed!
266 * removed!
267 *
268 * removed!
269 * removed!
270 * removed!
271 *
272 *------------------------------------------------------------------------------
273 * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
274 *==============================================================================
275 *******************************************************************************/
276
277#include "kal_public_api.h"
278#include "fs_general_api.h"
279
280#include "mcf_custom.h"
281#include "mcf_defs.h"
282#include "mcf_debug.h"
283#include "mcf_struct.h"
284#include "mcf_util.h"
285#include "mcf_object.h"
286#include "cust_chl_interface.h"
287#include "us_timer.h"
288#include <stdarg.h>
289#include "sleepdrv_interface.h"
290
291/*------------------------------------------------------------------------------
292 * Global variables.
293 *----------------------------------------------------------------------------*/
294mcf_t mcf_inst_g;
295kal_enhmutexid mcf_enhmutex_g = NULL;
296event_scheduler *mcf_timer_es_g = NULL;
297eventid mcf_timer_eventid_g = NULL;
298mcf_common_t com_Mcf;
299kal_enhmutexid mcf_utfwk_enhmutex_g = NULL;
300mcf_file_info_t new_file_info;
301mcf_file_info_t old_file_info;
302
303#undef BOOT_TRC_MSG
304#define BOOT_TRC_MSG(_name,_format) {_format},
305static MCF_BOOT_LOG boot_trace_format[] =
306{
307 #include "mcf_boot_trace.h"
308};
309
310/*------------------------------------------------------------------------------
311 * Helper macro.
312 *----------------------------------------------------------------------------*/
313
314/*------------------------------------------------------------------------------
315 * Private data structure.
316 *----------------------------------------------------------------------------*/
317
318/*------------------------------------------------------------------------------
319 * Private variables.
320 *----------------------------------------------------------------------------*/
321static KAL_ADM_ID mcf_mem_id = NULL;
322static kal_uint8 mcf_mem_pool[MCF_MAX_MEM_MALLOC_SIZE];
323static kal_bool mcf_mem_init_flag = KAL_FALSE;
324/*------------------------------------------------------------------------------
325 * Private fucntions.
326 *----------------------------------------------------------------------------*/
327extern kal_char* release_verno(void);
328extern kal_char* build_date_time(void);
329/*------------------------------------------------------------------------------
330 * Public fucntions.
331 *----------------------------------------------------------------------------*/
332#if !defined(__HIF_CCCI_SUPPORT__) || !defined(__MTK_TARGET__)
333kal_int32 MCF_dummy_FS_CMPT_Read(const WCHAR * FileName, NVRAM_FS_PARAM_CMPT_T* nvram_param)
334{
335 return FS_NO_ERROR;
336}
337#include <stdio.h>
338#include <windows.h>
339kal_int32 MCF_Win_FS_CMPT_Read(const WCHAR * FileName, NVRAM_FS_PARAM_CMPT_T* nvram_param)
340{
341 char fname[MCF_FILE_MAX_NAME_LEN] = { 0 };
342 char fullpath[MCF_FILE_MAX_MD_PATH_LEN + MCF_FILE_MAX_NAME_LEN] = { 0 };
343 kal_uint32 i = 0;
344 FILE *fd = NULL;
345 if (mcf_utfwk_is_working_status == KAL_TRUE){
346 return FS_NO_ERROR;
347 }
348
349 // translate wchar to char
350 WCHAR *ptr = FileName; // skip drive "S:"
351 while (*ptr != NULL) {
352 fname[i++] = (char)*ptr;
353 ptr++;
354 }
355
356 if (GetModuleFileName(NULL, fullpath, MCF_FILE_MAX_MD_PATH_LEN + MCF_FILE_MAX_NAME_LEN) != NULL) {
357 char *pch = strrchr(fullpath, '\\');
358 *(++pch) = 0;
359 strncat(fullpath, fname, MCF_FILE_MAX_MD_PATH_LEN + MCF_FILE_MAX_NAME_LEN - 1);
360 }
361 else {
362 return FS_FILE_NOT_FOUND;
363 }
364
365 // due to open & close operation are must, so always open & close file (ignore CCCI_FS_CMPT_OPEN & CCCI_FS_CMPT_CLOSE)
366 fd = fopen(fullpath, "rb");
367 if (fd == NULL)
368 return FS_FILE_NOT_FOUND;
369 //get file size
370 if (nvram_param->opid_map & CCCI_FS_CMPT_GETFILESIZE)
371 {
372 fseek(fd, 0, SEEK_END);
373 *nvram_param->FileSize = ftell(fd);
374 fseek(fd, 0, SEEK_SET);
375 }
376 // seek
377 if (nvram_param->opid_map & CCCI_FS_CMPT_SEEK)
378 {
379 fseek(fd, nvram_param->Offset, nvram_param->Whence);
380 }
381 // read
382 if (nvram_param->opid_map & CCCI_FS_CMPT_READ)
383 {
384 if (nvram_param->DataPtr != NULL) {
385 *nvram_param->Read = fread(nvram_param->DataPtr, nvram_param->Length, 1, fd);
386 }
387 }
388 fclose(fd);
389 return FS_NO_ERROR;
390}
391#endif
392
393void mcf_mem_init(void)
394{
395 if (mcf_mem_init_flag == KAL_FALSE)
396 {
397 mcf_mem_id = kal_adm_create((void*)mcf_mem_pool, sizeof(mcf_mem_pool), NULL, KAL_FALSE);
398 mcf_mem_init_flag = KAL_TRUE;
399 }
400}
401
402void *mcf_malloc(unsigned int size)
403{
404 mcf_mem_init();
405 if (NULL != mcf_mem_id) {
406 void *ret = kal_adm_alloc(mcf_mem_id, size);
407 if(ret == NULL)
408 {
409 MCF_BOOT_TRACE(MCF_BOOT_TR_ALLOC_MEM_ERROR);
410 MD_TRC_MCF_TR_ALLOC_MEM_ERROR();
411 }
412 return ret;
413 }
414 return NULL;
415}
416
417void mcf_free(void *ptr)
418{
419 if (NULL == mcf_mem_id) {
420 return;
421 }
422 kal_adm_free(mcf_mem_id, ptr);
423}
424
425void mcf_create_custom_folder(mcf_t *pMcf)
426{
427 kal_wchar foldername[MCF_FILE_MAX_MD_PATH_LEN] = {0};
428 kal_int32 fs_api_ret;
429
430 kal_wsprintf(foldername, "%s\0", MCF_FS_CUSTOM_FOLDER_PATH);
431 fs_api_ret = FS_CreateDir(foldername);
432 if (fs_api_ret < FS_NO_ERROR) {
433 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_CREATE_CUSTOM_FOLDER_FAIL;
434 MCF_BOOT_TRACE(MCF_BOOT_TR_CREATE_CUSTOM_FOLDER_FAIL, MCF_FS_CUSTOM_FOLDER_PATH, fs_api_ret);
435 }
436
437 return;
438}
439
440mcf_ota_result_e mcf_read_ota_file(
441 kal_bool is_booting,
442 kal_char *req_fs_root_path,
443 kal_char *req_file_path_name,
444 l4c_mcf_path_type_enum *apply_path_type,
445 kal_char *apply_filename,
446 mcf_t *pMcf)
447{
448 NVRAM_FS_PARAM_CMPT_T fs_cmpt;
449 FS_FileDetail fs_file_detail[L4C_MCF_PATH_TYPE_MAX] = {0};
450 kal_uint32 read_byte = 0;
451 kal_uint32 file_size = 0;
452 mcf_ota_result_e ret = MCF_OTA_R_SUCCESS;
453 mcf_ota_file_t *ota_file = &(pMcf->ota_file);
454 kal_wchar filename[MCF_FILE_MAX_MD_PATH_LEN + MCF_FILE_MAX_NAME_LEN];
455 mcf_tool_file_info_t *pFile;
456 kal_char password[MCF_MAX_PASSWORD_LEN] = {0};
457 kal_bool is_get_custom_filename = KAL_FALSE;
458 kal_bool is_default_path;
459 kal_uint32 dummy_para;
460 kal_int32 fs_api_ret[L4C_MCF_PATH_TYPE_MAX];
461 kal_uint64 last_mod_time = 0;
462 kal_char default_file_name_tag[30];
463 kal_uint64 ini_path_ota_file_last_mod_time = 0;
464 kal_uint64 ini_path_runtime_file_last_mod_time = 0;
465 kal_char ini_root_path[20];
466
467 fs_cmpt.opid_map = NVRAM_FS_CMPT_OPEN | NVRAM_FS_CMPT_GETFILESIZE | NVRAM_FS_CMPT_CLOSE;
468 fs_cmpt.Flag = FS_READ_ONLY;
469 fs_cmpt.Length = 0;
470 fs_cmpt.Offset = 0;
471 fs_cmpt.Whence = FS_FILE_BEGIN;
472 fs_cmpt.DataPtr = &dummy_para;
473 fs_cmpt.Read = &dummy_para;
474 fs_cmpt.FileSize = &file_size;
475
476 if ( (strcmp(req_fs_root_path, "") != 0) && (strcmp(req_file_path_name, "") != 0) ) {
477 if (strcmp(req_fs_root_path, MCF_FS_DEFAULT_FOLDER_PATH) == 0) {
478 *apply_path_type = L4C_MCF_PATH_TYPE_OTA;
479 } else if (strcmp(req_fs_root_path, MCF_FS_CUSTOM_FOLDER_PATH) == 0) {
480 *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME;
481 }else{
482 MD_TRC_MCF_TR_READ_OTA_FILE_INVALID_PATH(req_fs_root_path);
483 ret = MCF_OTA_R_INVALID_PARAMETER;
484
485 return ret;
486 }
487 kal_wsprintf(filename, "%s\\%s\0", req_fs_root_path, req_file_path_name);
488 strncpy(apply_filename, req_file_path_name, MCF_FILE_MAX_NAME_LEN - 1);
489 is_default_path = KAL_FALSE;
490 } else {
491 is_get_custom_filename = mcf_get_custom_file_path_name((kal_uint8 *)apply_path_type, apply_filename);
492 strncpy(default_file_name_tag, "Default_OTA_File_Name", 29);
493 if (is_get_custom_filename == KAL_TRUE) {
494 if (*apply_path_type >= L4C_MCF_PATH_TYPE_MAX || *apply_path_type < 0) {
495 MD_TRC_MCF_TR_READ_OTA_FILE_INVALID_PATH_TYPE(*apply_path_type);
496 ret = MCF_OTA_R_INVALID_PARAMETER;
497
498 return ret;
499 }
500
501 if (*apply_path_type == L4C_MCF_PATH_TYPE_OTA) {
502 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, apply_filename);
503 } else if (*apply_path_type == L4C_MCF_PATH_TYPE_RUNTIME) {
504 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, apply_filename);
505 }
506 }
507 else {
508 /* Try to read default ota file name in INI file */
509 /* Compare modified time of ini file to select which file to be applied */
510 if(mcf_get_file_last_mod_time (MCF_FS_DEFAULT_INI_FILE_NAME, L4C_MCF_PATH_TYPE_OTA, &ini_path_ota_file_last_mod_time) == MCF_OTA_R_READ_OTA_FILE_FAIL){
511 ini_path_ota_file_last_mod_time = 0;
512 MD_TRC_MCF_TR_READ_OTA_FILE_READ_INI_FILE_FAIL(L4C_MCF_PATH_TYPE_OTA, MCF_OTA_R_READ_OTA_FILE_FAIL);
513
514 if (mcf_get_file_last_mod_time (MCF_FS_DEFAULT_INI_FILE_NAME, L4C_MCF_PATH_TYPE_RUNTIME, &ini_path_runtime_file_last_mod_time) == MCF_OTA_R_READ_OTA_FILE_FAIL){
515 ini_path_runtime_file_last_mod_time = 0;
516 MD_TRC_MCF_TR_READ_OTA_FILE_READ_INI_FILE_FAIL(L4C_MCF_PATH_TYPE_RUNTIME, MCF_OTA_R_READ_OTA_FILE_FAIL);
517 }
518 }
519
520 if(mcf_get_file_last_mod_time (MCF_FS_DEFAULT_INI_FILE_NAME, L4C_MCF_PATH_TYPE_RUNTIME, &ini_path_runtime_file_last_mod_time) == MCF_OTA_R_READ_OTA_FILE_FAIL){
521 ini_path_runtime_file_last_mod_time = 0;
522 MD_TRC_MCF_TR_READ_OTA_FILE_READ_INI_FILE_FAIL(L4C_MCF_PATH_TYPE_RUNTIME, MCF_OTA_R_READ_OTA_FILE_FAIL);
523
524 if(mcf_get_file_last_mod_time (MCF_FS_DEFAULT_INI_FILE_NAME, L4C_MCF_PATH_TYPE_OTA, &ini_path_ota_file_last_mod_time) == MCF_OTA_R_READ_OTA_FILE_FAIL){
525 ini_path_ota_file_last_mod_time = 0;
526 MD_TRC_MCF_TR_READ_OTA_FILE_READ_INI_FILE_FAIL(L4C_MCF_PATH_TYPE_OTA, MCF_OTA_R_READ_OTA_FILE_FAIL);
527 }
528 }
529
530 kal_mem_set(ini_root_path,0,20);
531 if (ini_path_ota_file_last_mod_time > ini_path_runtime_file_last_mod_time){
532 strncpy(ini_root_path,MCF_FS_DEFAULT_FOLDER_PATH, 19);
533 }else{
534 strncpy(ini_root_path,MCF_FS_CUSTOM_FOLDER_PATH, 19);
535 }
536 if (mcf_read_ini_file(ini_root_path , MCF_FS_DEFAULT_INI_FILE_NAME, apply_path_type, apply_filename, pMcf) == MCF_OTA_R_SUCCESS &&
537 mcf_find_ini_item((kal_char *)pMcf->ini_file.buff, default_file_name_tag, apply_filename, pMcf) == KAL_TRUE && strcmp(apply_filename, "") != 0) {
538 strncat (apply_filename,".mcfota", MCF_FILE_MAX_NAME_LEN - 1);
539 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, apply_filename);
540 MCF_BOOT_TRACE(MCF_BOOT_TR_DO_OTA_FULL_GET_DEFAULT_OTA_FILE_NAME_FROM_INI, apply_filename);
541
542 }else{
543 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_DEFAULT_OTA_FILE_NAME);
544 strncpy(apply_filename, MCF_FS_DEFAULT_OTA_FILE_NAME, MCF_FILE_MAX_NAME_LEN - 1);
545 }
546
547 /* Compare modified time of OTA file to select which file to be applied */
548 fs_api_ret[L4C_MCF_PATH_TYPE_OTA] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_OTA]);
549 MD_TRC_MCF_TR_READ_OTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_OTA, fs_api_ret[L4C_MCF_PATH_TYPE_OTA],
550 (kal_uint32)((fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime & 0xFFFFFFFF));
551 if (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] != FS_NO_ERROR) {
552 kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_OTA], 0, sizeof(FS_FileDetail));
553 }
554
555 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_DEFAULT_OTA_FILE_NAME);
556 fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME]);
557 MD_TRC_MCF_TR_READ_OTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_RUNTIME, fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME],
558 (kal_uint32)((fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime & 0xFFFFFFFF));
559 if (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] != FS_NO_ERROR) {
560 kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME], 0, sizeof(FS_FileDetail));
561 }
562
563 if ( (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] == FS_NO_ERROR) || (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] == FS_NO_ERROR) ) {
564 if (fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime > fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime) {
565 *apply_path_type = L4C_MCF_PATH_TYPE_OTA;
566 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, apply_filename);
567 } else {
568 *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME;
569 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_DEFAULT_OTA_FILE_NAME);
570 }
571 } else {
572 if (is_booting == KAL_TRUE) {
573 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL;
574 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_COMPARE_FAIL);
575 }
576 MD_TRC_MCF_TR_READ_OTA_FILE_COMPARE_FAIL();
577 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
578
579 return ret;
580 }
581
582 }
583 is_default_path = KAL_TRUE;
584 }
585
586 fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt);
587 if (fs_api_ret[0] < FS_NO_ERROR) {
588 if (is_booting == KAL_TRUE) {
589 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_FAIL, *apply_path_type, fs_api_ret[0]);
590 MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename);
591 }
592 MD_TRC_MCF_TR_READ_OTA_FILE_FAIL(*apply_path_type, fs_api_ret[0]);
593 dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename);
594
595 /* If cannot read given OTA file, read default OTA file */
596 if (is_default_path == KAL_FALSE) {
597 is_get_custom_filename = mcf_get_custom_file_path_name((kal_uint8 *)apply_path_type, apply_filename);
598 if (*apply_path_type >= L4C_MCF_PATH_TYPE_MAX || *apply_path_type < 0) {
599 MD_TRC_MCF_TR_READ_OTA_FILE_INVALID_PATH_TYPE(*apply_path_type);
600 ret = MCF_OTA_R_INVALID_PARAMETER;
601
602 return ret;
603 }
604
605 if (is_get_custom_filename == KAL_TRUE) {
606 if (*apply_path_type == L4C_MCF_PATH_TYPE_OTA) {
607 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, apply_filename);
608 } else if (*apply_path_type == L4C_MCF_PATH_TYPE_RUNTIME) {
609 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, apply_filename);
610 }
611 } else {
612 /* Compare modified time of OTA file to select which file to be applied */
613 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_DEFAULT_OTA_FILE_NAME);
614 fs_api_ret[L4C_MCF_PATH_TYPE_OTA] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_OTA]);
615 MD_TRC_MCF_TR_READ_OTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_OTA, fs_api_ret[L4C_MCF_PATH_TYPE_OTA],
616 (kal_uint32)((fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime & 0xFFFFFFFF));
617 if (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] != FS_NO_ERROR) {
618 kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_OTA], 0, sizeof(FS_FileDetail));
619 }
620
621 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_DEFAULT_OTA_FILE_NAME);
622 fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME]);
623 MD_TRC_MCF_TR_READ_OTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_RUNTIME, fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME],
624 (kal_uint32)((fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime & 0xFFFFFFFF));
625 if (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] != FS_NO_ERROR) {
626 kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME], 0, sizeof(FS_FileDetail));
627 }
628
629 if ( (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] == FS_NO_ERROR) || (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] == FS_NO_ERROR) ) {
630 if (fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime > fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime) {
631 *apply_path_type = L4C_MCF_PATH_TYPE_OTA;
632 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_DEFAULT_OTA_FILE_NAME);
633 } else {
634 *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME;
635 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_DEFAULT_OTA_FILE_NAME);
636 }
637 } else {
638 if (is_booting == KAL_TRUE) {
639 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL;
640 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_COMPARE_FAIL);
641 }
642 MD_TRC_MCF_TR_READ_OTA_FILE_COMPARE_FAIL();
643 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
644
645 return ret;
646 }
647
648 strncpy(apply_filename, MCF_FS_DEFAULT_OTA_FILE_NAME, MCF_FILE_MAX_NAME_LEN - 1);
649
650 }
651
652 fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt);
653 if (fs_api_ret[0] < FS_NO_ERROR) {
654 if (is_booting == KAL_TRUE) {
655 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL;
656 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_FAIL, *apply_path_type, fs_api_ret[0]);
657 MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename);
658 }
659 MD_TRC_MCF_TR_READ_OTA_FILE_FAIL(*apply_path_type, fs_api_ret[0]);
660 dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename);
661 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
662
663 return ret;
664 }
665 } else {
666 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
667
668 return ret;
669 }
670 }
671
672 if (file_size > MCF_MAX_OTA_FILE_SIZE) {
673 if (is_booting == KAL_TRUE) {
674 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_OTA_FILE_OVERSIZE;
675 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_OVERSIZE, file_size, MCF_MAX_OTA_FILE_SIZE);
676 }
677 MD_TRC_MCF_TR_READ_OTA_FILE_OVERSIZE(file_size, MCF_MAX_OTA_FILE_SIZE);
678 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
679
680 return ret;
681 }
682
683 /* Read file */
684 fs_cmpt.opid_map = NVRAM_FS_CMPT_OPEN | NVRAM_FS_CMPT_READ | NVRAM_FS_CMPT_CLOSE;
685 fs_cmpt.Flag = FS_READ_ONLY;
686 fs_cmpt.Length = file_size;
687 fs_cmpt.Offset = 0;
688 fs_cmpt.Whence = FS_FILE_BEGIN;
689 fs_cmpt.DataPtr = ota_file->buff;
690 fs_cmpt.Read = &read_byte;
691 fs_cmpt.FileSize = &dummy_para;
692
693 fs_api_ret[*apply_path_type] = FS_GetFileDetail(filename, &fs_file_detail[*apply_path_type]);
694 MD_TRC_MCF_TR_READ_OTA_FILE_MODIFIED_TIME(*apply_path_type, fs_api_ret[*apply_path_type],
695 (kal_uint32)((fs_file_detail[*apply_path_type].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[*apply_path_type].LastStatusChangeTime & 0xFFFFFFFF));
696 if (fs_api_ret[*apply_path_type] == FS_NO_ERROR) {
697 last_mod_time = fs_file_detail[*apply_path_type].LastStatusChangeTime;
698 } else {
699 if (is_booting == KAL_TRUE) {
700 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL;
701 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_FAIL, *apply_path_type, fs_api_ret[*apply_path_type]);
702 MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename);
703 }
704 MD_TRC_MCF_TR_READ_OTA_FILE_FAIL(*apply_path_type, fs_api_ret[*apply_path_type]);
705 dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename);
706 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
707
708 return ret;
709 }
710
711 MCF_W_LOCK_OBJECT(ota_file, mcf_enhmutex_g);
712 if (ota_file) {
713 fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt);
714 if (fs_api_ret[0] < FS_NO_ERROR) {
715 MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g);
716 if (is_booting == KAL_TRUE) {
717 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL;
718 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_FAIL, *apply_path_type, fs_api_ret[0]);
719 MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename);
720 }
721 MD_TRC_MCF_TR_READ_OTA_FILE_FAIL(*apply_path_type, fs_api_ret[0]);
722 dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename);
723 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
724
725 return ret;
726 }
727
728 pFile = (mcf_tool_file_info_t *)(ota_file->buff);
729#ifdef __MCF_FIND_TAG_SUPPORT__
730 if (pFile->file_version == 2 || pFile->file_version == 3) {
731#else
732 if (pFile->file_version == 3) {
733#endif
734 kal_uint32 operation_mask = 0;
735
736 /* Check custom operation mask */
737 operation_mask = mcf_get_custom_operation_mask();
738 if ((pFile->operation_mask & operation_mask) != operation_mask) {
739 if (is_booting == KAL_TRUE) {
740 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_OPERATION_MASK_FAIL;
741 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_OPERATION_MASK_FAIL, apply_filename, pFile->operation_mask, operation_mask);
742 }
743 MD_TRC_MCF_TR_READ_OTA_FILE_OPERATION_MASK_FAIL(apply_filename, pFile->operation_mask, operation_mask);
744 ret = MCF_OTA_R_INVALID_FILE;
745
746 kal_mem_set(ota_file->buff, 0, MCF_MAX_OTA_FILE_SIZE);
747 kal_mem_set(ota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
748 ota_file->path_type = 0;
749 ota_file->last_mod_time = 0;
750 MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g);
751
752 return ret;
753 }
754
755 /* First check digest first
756 * If file is encrypted and has checksum.
757 * Decrypt file before checking checksum.
758 */
759
760 // RSA verify digest
761 if ((pFile->operation_mask & MCF_FILE_OP_SHA256_RSA2048) != 0) {
762
763 if (mcf_verify_digest(MCF_FILE_OP_SHA256_RSA2048, (mcf_tool_file_info_t *)(ota_file->buff), (mcf_digest *)(ota_file->buff + pFile->file_size)) != KAL_TRUE) {
764 kal_mem_set(ota_file->buff, 0, MCF_MAX_OTA_FILE_SIZE);
765 kal_mem_set(ota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
766 ota_file->path_type = 0;
767 ota_file->last_mod_time = 0;
768 MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g);
769 if (is_booting == KAL_TRUE) {
770 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DIGEST_FAIL;
771 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_DIGEST_FAIL, apply_filename);
772 }
773 MD_TRC_MCF_TR_READ_OTA_FILE_DIGEST_FAIL(apply_filename);
774 ret = MCF_OTA_R_DIGEST_FAIL;
775
776 return ret;
777 }
778
779 }
780
781 else if ((pFile->operation_mask & MCF_FILE_OP_SHA384_RSA3072) != 0) {
782
783 if (mcf_verify_digest(MCF_FILE_OP_SHA384_RSA3072, (mcf_tool_file_info_t *)(ota_file->buff), (mcf_digest *)(ota_file->buff + pFile->file_size)) != KAL_TRUE) {
784 kal_mem_set(ota_file->buff, 0, MCF_MAX_OTA_FILE_SIZE);
785 kal_mem_set(ota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
786 ota_file->path_type = 0;
787 ota_file->last_mod_time = 0;
788 MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g);
789 if (is_booting == KAL_TRUE) {
790 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DIGEST_FAIL;
791 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_DIGEST_FAIL, apply_filename);
792 }
793 MD_TRC_MCF_TR_READ_OTA_FILE_DIGEST_FAIL(apply_filename);
794 ret = MCF_OTA_R_DIGEST_FAIL;
795
796 return ret;
797 }
798
799 }
800
801 if ( (pFile->operation_mask & MCF_FILE_OP_AES_128) != 0) {
802 mcf_get_custom_aes_password(password);
803
804 if (mcf_decrypt_128bit(password, (kal_char *)(ota_file->buff + pFile->total_len), (pFile->file_size - pFile->total_len) ) != KAL_TRUE) {
805 kal_mem_set(ota_file->buff, 0, MCF_MAX_OTA_FILE_SIZE);
806 kal_mem_set(ota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
807 ota_file->path_type = 0;
808 ota_file->last_mod_time = 0;
809 MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g);
810 if (is_booting == KAL_TRUE) {
811 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DECRYPTION_FAIL;
812 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_DECRYPTION_FAIL, apply_filename);
813 }
814 MD_TRC_MCF_TR_READ_OTA_FILE_DECRYPTION_FAIL(apply_filename);
815 ret = MCF_OTA_R_DECRYPTION_FAIL;
816
817 return ret;
818 }
819 }
820 // for AES_256
821 else if ((pFile->operation_mask & MCF_FILE_OP_AES_256) != 0) {
822 mcf_get_custom_aes_password(password);
823 if (mcf_decrypt_256bit(password, (kal_char *)(ota_file->buff + pFile->total_len), (pFile->file_size - pFile->total_len)) != KAL_TRUE) {
824 kal_mem_set(ota_file->buff, 0, MCF_MAX_OTA_FILE_SIZE);
825 kal_mem_set(ota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
826 ota_file->path_type = 0;
827 ota_file->last_mod_time = 0;
828 MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g);
829 if (is_booting == KAL_TRUE) {
830 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DECRYPTION_FAIL;
831 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_DECRYPTION_FAIL, apply_filename);
832 }
833 MD_TRC_MCF_TR_READ_OTA_FILE_DECRYPTION_FAIL(apply_filename);
834 ret = MCF_OTA_R_DECRYPTION_FAIL;
835
836 return ret;
837 }
838 }
839
840 if ( (pFile->operation_mask & MCF_FILE_OP_CHECKSUM) != 0) {
841 if (mcf_check_check_sum((kal_uint32 *)(ota_file->buff), pFile->file_size) != 0) {
842 kal_mem_set(ota_file->buff, 0, MCF_MAX_OTA_FILE_SIZE);
843 kal_mem_set(ota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
844 ota_file->path_type = 0;
845 ota_file->last_mod_time = 0;
846 MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g);
847 if (is_booting == KAL_TRUE) {
848 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_CHECKSUM_ERROR;
849 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_CHECKSUM_ERROR, apply_filename);
850 }
851 MD_TRC_MCF_TR_READ_OTA_FILE_CHECKSUM_ERROR(apply_filename);
852 ret = MCF_OTA_R_CHECKSUM_ERROR;
853
854 return ret;
855 }
856 }
857 } else {
858 if (is_booting == KAL_TRUE) {
859 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_INVALID_FILE;
860 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_INVALID_FILE_VERSION, pFile->file_version);
861 }
862 MD_TRC_MCF_TR_READ_OTA_FILE_INVALID_FILE_VERSION(pFile->file_version);
863 kal_mem_set(ota_file->buff, 0, MCF_MAX_OTA_FILE_SIZE);
864 kal_mem_set(ota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
865 ota_file->path_type = 0;
866 ota_file->last_mod_time = 0;
867 MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g);
868 ret = MCF_OTA_R_INVALID_FILE;
869
870 return ret;
871 }
872
873 ota_file->path_type = *apply_path_type;
874 ota_file->last_mod_time = last_mod_time;
875#if defined(__MCF_UT_FRAMEWORK_SUPPORT__)
876 if (strcmp(ota_file->relative_path_name, "") == 0){
877 strncpy(ota_file->relative_path_name, apply_filename, MCF_FILE_MAX_NAME_LEN - 1);
878 }else{
879 strncpy(apply_filename, ota_file->relative_path_name, MCF_FILE_MAX_NAME_LEN - 1);
880 }
881#else
882 strncpy(ota_file->relative_path_name, apply_filename, MCF_FILE_MAX_NAME_LEN - 1);
883#endif
884 MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g);
885 } else {
886 if (is_booting == KAL_TRUE) {
887 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_TAKE_WRITE_LOCK_FAIL;
888 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_TAKE_WRITE_LOCK_FAIL, apply_filename, *apply_path_type);
889 }
890 MD_TRC_MCF_TR_READ_OTA_FILE_TAKE_WRITE_LOCK_FAIL(apply_filename, *apply_path_type);
891 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
892 }
893
894 return ret;
895}
896
897mcf_ota_result_e mcf_read_tlvota_file(
898 kal_bool is_booting,
899 kal_uint8 sim_id,
900 kal_char *req_fs_root_path,
901 kal_char *req_file_path_name,
902 l4c_mcf_path_type_enum *apply_path_type,
903 kal_char *apply_filename,
904 mcf_t *pMcf)
905{
906 NVRAM_FS_PARAM_CMPT_T fs_cmpt;
907 FS_FileDetail fs_file_detail[L4C_MCF_PATH_TYPE_MAX] = {0};
908 kal_uint32 read_byte = 0;
909 kal_uint32 file_size = 0;
910 mcf_ota_result_e ret = MCF_OTA_R_SUCCESS;
911 mcf_tlvota_file_t *tlvota_file = &(pMcf->tlvota_file[sim_id]);
912 kal_wchar filename[MCF_FILE_MAX_MD_PATH_LEN + MCF_FILE_MAX_NAME_LEN];
913 mcf_tool_file_info_t *pFile;
914 kal_char password[MCF_MAX_PASSWORD_LEN] = {0};
915 kal_bool is_default_path;
916 kal_uint32 dummy_para;
917 kal_int32 fs_api_ret[L4C_MCF_PATH_TYPE_MAX];
918 kal_uint64 last_mod_time = 0;
919
920 fs_cmpt.opid_map = NVRAM_FS_CMPT_OPEN | NVRAM_FS_CMPT_GETFILESIZE | NVRAM_FS_CMPT_CLOSE;
921 fs_cmpt.Flag = FS_READ_ONLY;
922 fs_cmpt.Length = 0;
923 fs_cmpt.Offset = 0;
924 fs_cmpt.Whence = FS_FILE_BEGIN;
925 fs_cmpt.DataPtr = &dummy_para;
926 fs_cmpt.Read = &dummy_para;
927 fs_cmpt.FileSize = &file_size;
928
929 if ( (strcmp(req_fs_root_path, "") != 0) && (strcmp(req_file_path_name, "") != 0) ) {
930 if (strcmp(req_fs_root_path, MCF_FS_DEFAULT_FOLDER_PATH) == 0) {
931 *apply_path_type = L4C_MCF_PATH_TYPE_OTA;
932 } else if (strcmp(req_fs_root_path, MCF_FS_CUSTOM_FOLDER_PATH) == 0) {
933 *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME;
934 } else{
935 MD_TRC_MCF_TR_READ_TLVOTA_FILE_INVALID_PATH(req_fs_root_path);
936 ret = MCF_OTA_R_INVALID_PARAMETER;
937
938 return ret;
939 }
940 kal_wsprintf(filename, "%s\\%s\0", req_fs_root_path, req_file_path_name);
941 strncpy(apply_filename, req_file_path_name, MCF_FILE_MAX_NAME_LEN - 1);
942 is_default_path = KAL_FALSE;
943 } else {
944 /* Compare modified time of OP-OTA file to select which file to be applied */
945 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_DEFAULT_TLVOTA_FILE_NAME);
946 fs_api_ret[L4C_MCF_PATH_TYPE_OTA] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_OTA]);
947 MD_TRC_MCF_TR_READ_TLVOTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_OTA, fs_api_ret[L4C_MCF_PATH_TYPE_OTA],
948 (kal_uint32)((fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime & 0xFFFFFFFF));
949 if (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] != FS_NO_ERROR) {
950 kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_OTA], 0, sizeof(FS_FileDetail));
951 }
952
953 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_DEFAULT_TLVOTA_FILE_NAME);
954 fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME]);
955 MD_TRC_MCF_TR_READ_TLVOTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_RUNTIME, fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME],
956 (kal_uint32)((fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime & 0xFFFFFFFF));
957 if (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] != FS_NO_ERROR) {
958 kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME], 0, sizeof(FS_FileDetail));
959 }
960
961 if ( (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] == FS_NO_ERROR) || (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] == FS_NO_ERROR) ) {
962 if (fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime > fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime) {
963 *apply_path_type = L4C_MCF_PATH_TYPE_OTA;
964 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_DEFAULT_TLVOTA_FILE_NAME);
965 } else {
966 *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME;
967 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_DEFAULT_TLVOTA_FILE_NAME);
968 }
969 } else {
970 if (is_booting == KAL_TRUE) {
971 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL;
972 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_COMPARE_FAIL);
973 }
974 MD_TRC_MCF_TR_READ_TLVOTA_FILE_COMPARE_FAIL();
975 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
976
977 return ret;
978 }
979
980 strncpy(apply_filename, MCF_FS_DEFAULT_TLVOTA_FILE_NAME, MCF_FILE_MAX_NAME_LEN - 1);
981
982 is_default_path = KAL_TRUE;
983 }
984
985 fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt);
986 if (fs_api_ret[0] < FS_NO_ERROR) {
987 if (is_booting == KAL_TRUE) {
988 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_FAIL, *apply_path_type, sim_id, fs_api_ret[0]);
989 MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename);
990 }
991 MD_TRC_MCF_TR_READ_TLVOTA_FILE_FAIL(*apply_path_type, sim_id, fs_api_ret[0]);
992 dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename);
993
994 /* If cannot read given TLV-OTA file, read default TLV-OTA file */
995 if (is_default_path == KAL_FALSE) {
996 /* Compare modified time of OP-OTA file to select which file to be applied */
997 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_DEFAULT_TLVOTA_FILE_NAME);
998 fs_api_ret[L4C_MCF_PATH_TYPE_OTA] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_OTA]);
999 MD_TRC_MCF_TR_READ_TLVOTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_OTA, fs_api_ret[L4C_MCF_PATH_TYPE_OTA],
1000 (kal_uint32)((fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime & 0xFFFFFFFF));
1001 if (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] != FS_NO_ERROR) {
1002 kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_OTA], 0, sizeof(FS_FileDetail));
1003 }
1004
1005 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_DEFAULT_TLVOTA_FILE_NAME);
1006 fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME]);
1007 MD_TRC_MCF_TR_READ_TLVOTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_RUNTIME, fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME],
1008 (kal_uint32)((fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime & 0xFFFFFFFF));
1009 if (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] != FS_NO_ERROR) {
1010 kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME], 0, sizeof(FS_FileDetail));
1011 }
1012
1013 if ( (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] == FS_NO_ERROR) || (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] == FS_NO_ERROR) ) {
1014 if (fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime > fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime) {
1015 *apply_path_type = L4C_MCF_PATH_TYPE_OTA;
1016 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_DEFAULT_TLVOTA_FILE_NAME);
1017 } else {
1018 *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME;
1019 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_DEFAULT_TLVOTA_FILE_NAME);
1020 }
1021 } else {
1022 if (is_booting == KAL_TRUE) {
1023 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL;
1024 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_COMPARE_FAIL);
1025 }
1026 MD_TRC_MCF_TR_READ_TLVOTA_FILE_COMPARE_FAIL();
1027 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
1028
1029 return ret;
1030 }
1031
1032 strncpy(apply_filename, MCF_FS_DEFAULT_TLVOTA_FILE_NAME, MCF_FILE_MAX_NAME_LEN - 1);
1033
1034 fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt);
1035 if (fs_api_ret[0] < FS_NO_ERROR) {
1036 if (is_booting == KAL_TRUE) {
1037 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_TLVOTA_FILE_FAIL;
1038 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_FAIL, *apply_path_type, sim_id, fs_api_ret[0]);
1039 MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename);
1040 }
1041 MD_TRC_MCF_TR_READ_TLVOTA_FILE_FAIL(*apply_path_type, sim_id, fs_api_ret[0]);
1042 dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename);
1043 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
1044
1045 return ret;
1046 }
1047 } else {
1048 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
1049
1050 return ret;
1051 }
1052 }
1053
1054 if (file_size > MCF_MAX_TLVOTA_FILE_SIZE) {
1055 if (is_booting == KAL_TRUE) {
1056 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_TLVOTA_FILE_OVERSIZE;
1057 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_OVERSIZE, file_size, MCF_MAX_TLVOTA_FILE_SIZE);
1058 }
1059 MD_TRC_MCF_TR_READ_TLVOTA_FILE_OVERSIZE(file_size, MCF_MAX_TLVOTA_FILE_SIZE);
1060 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
1061
1062 return ret;
1063 }
1064
1065 /* Read file */
1066 fs_cmpt.opid_map = NVRAM_FS_CMPT_OPEN | NVRAM_FS_CMPT_READ | NVRAM_FS_CMPT_CLOSE;
1067 fs_cmpt.Flag = FS_READ_ONLY;
1068 fs_cmpt.Length = file_size;
1069 fs_cmpt.Offset = 0;
1070 fs_cmpt.Whence = FS_FILE_BEGIN;
1071 fs_cmpt.DataPtr = tlvota_file->buff;
1072 fs_cmpt.Read = &read_byte;
1073 fs_cmpt.FileSize = &dummy_para;
1074
1075 fs_api_ret[*apply_path_type] = FS_GetFileDetail(filename, &fs_file_detail[*apply_path_type]);
1076 MD_TRC_MCF_TR_READ_TLVOTA_FILE_MODIFIED_TIME(*apply_path_type, fs_api_ret[*apply_path_type],
1077 (kal_uint32)((fs_file_detail[*apply_path_type].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[*apply_path_type].LastStatusChangeTime & 0xFFFFFFFF));
1078 if (fs_api_ret[*apply_path_type] == FS_NO_ERROR) {
1079 last_mod_time = fs_file_detail[*apply_path_type].LastStatusChangeTime;
1080 } else {
1081 if (is_booting == KAL_TRUE) {
1082 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_TLVOTA_FILE_FAIL;
1083 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_FAIL, *apply_path_type, sim_id, fs_api_ret[0]);
1084 MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename);
1085 }
1086 MD_TRC_MCF_TR_READ_TLVOTA_FILE_FAIL(*apply_path_type, sim_id, fs_api_ret[*apply_path_type]);
1087 dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename);
1088 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
1089
1090 return ret;
1091 }
1092
1093 MCF_W_LOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1094 if (tlvota_file) {
1095 fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt);
1096 if (fs_api_ret[0] < FS_NO_ERROR) {
1097 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1098 if (is_booting == KAL_TRUE) {
1099 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_TLVOTA_FILE_FAIL;
1100 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_FAIL, *apply_path_type, sim_id, fs_api_ret[0]);
1101 MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename);
1102 }
1103 MD_TRC_MCF_TR_READ_TLVOTA_FILE_FAIL(*apply_path_type, sim_id, fs_api_ret[0]);
1104 dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename);
1105 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
1106
1107 return ret;
1108 }
1109
1110 pFile = (mcf_tool_file_info_t *)(tlvota_file->buff);
1111#ifdef __MCF_FIND_TAG_SUPPORT__
1112 if (pFile->file_version == 2 || pFile->file_version == 3) {
1113#else
1114 if (pFile->file_version == 3) {
1115#endif
1116 kal_uint32 operation_mask = 0;
1117
1118 /* Check custom operation mask */
1119 operation_mask = mcf_get_custom_operation_mask();
1120 if ((pFile->operation_mask & operation_mask) != operation_mask) {
1121 if (is_booting == KAL_TRUE) {
1122 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_OPERATION_MASK_FAIL;
1123 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_OPERATION_MASK_FAIL, apply_filename, pFile->operation_mask, operation_mask);
1124 }
1125 MD_TRC_MCF_TR_READ_TLVOTA_FILE_OPERATION_MASK_FAIL(apply_filename, pFile->operation_mask, operation_mask);
1126 ret = MCF_OTA_R_INVALID_FILE;
1127
1128 kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE);
1129 kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
1130 tlvota_file->path_type = 0;
1131 tlvota_file->last_mod_time = 0;
1132 kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t));
1133 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1134
1135 return ret;
1136 }
1137
1138 /* First check digest first
1139 * If file is encrypted and has checksum.
1140 * Decrypt file before checking checksum.
1141 */
1142 // RSA verify digest
1143 if ((pFile->operation_mask & MCF_FILE_OP_SHA256_RSA2048) != 0) {
1144
1145 if (mcf_verify_digest(MCF_FILE_OP_SHA256_RSA2048, (mcf_tool_file_info_t *)(tlvota_file->buff), (mcf_digest *)(tlvota_file->buff + pFile->file_size)) != KAL_TRUE) {
1146 kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE);
1147 kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
1148 tlvota_file->path_type = 0;
1149 tlvota_file->last_mod_time = 0;
1150 kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t));
1151 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1152 if (is_booting == KAL_TRUE) {
1153 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DIGEST_FAIL;
1154 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_DIGEST_FAIL, apply_filename);
1155 }
1156 MD_TRC_MCF_TR_READ_TLVOTA_FILE_DIGEST_FAIL(apply_filename);
1157 ret = MCF_OTA_R_DIGEST_FAIL;
1158
1159 return ret;
1160 }
1161
1162 }
1163 else if ((pFile->operation_mask & MCF_FILE_OP_SHA384_RSA3072) != 0) {
1164
1165 if (mcf_verify_digest(MCF_FILE_OP_SHA384_RSA3072, (mcf_tool_file_info_t *)(tlvota_file->buff), (mcf_digest *)(tlvota_file->buff + pFile->file_size)) != KAL_TRUE) {
1166 kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE);
1167 kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
1168 tlvota_file->path_type = 0;
1169 tlvota_file->last_mod_time = 0;
1170 kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t));
1171 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1172 if (is_booting == KAL_TRUE) {
1173 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DIGEST_FAIL;
1174 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_DIGEST_FAIL, apply_filename);
1175 }
1176 MD_TRC_MCF_TR_READ_TLVOTA_FILE_DIGEST_FAIL(apply_filename);
1177 ret = MCF_OTA_R_DIGEST_FAIL;
1178
1179 return ret;
1180 }
1181
1182 }
1183
1184 if ( (pFile->operation_mask & MCF_FILE_OP_AES_128) != 0) {
1185 mcf_get_custom_aes_password(password);
1186
1187 if (mcf_decrypt_128bit(password, (kal_char *)(tlvota_file->buff + pFile->total_len), (pFile->file_size - pFile->total_len) ) != KAL_TRUE) {
1188 kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE);
1189 kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
1190 tlvota_file->path_type = 0;
1191 tlvota_file->last_mod_time = 0;
1192 kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t));
1193 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1194 if (is_booting == KAL_TRUE) {
1195 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DECRYPTION_FAIL;
1196 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_DECRYPTION_FAIL, apply_filename);
1197 }
1198 MD_TRC_MCF_TR_READ_TLVOTA_FILE_DECRYPTION_FAIL(apply_filename);
1199 ret = MCF_OTA_R_DECRYPTION_FAIL;
1200
1201 return ret;
1202 }
1203 }
1204 else if ((pFile->operation_mask & MCF_FILE_OP_AES_256) != 0) { // for AES_256
1205 mcf_get_custom_aes_password(password);
1206
1207 if (mcf_decrypt_256bit(password, (kal_char *)(tlvota_file->buff + pFile->total_len), (pFile->file_size - pFile->total_len)) != KAL_TRUE) {
1208 kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE);
1209 kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
1210 tlvota_file->path_type = 0;
1211 tlvota_file->last_mod_time = 0;
1212 kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t));
1213 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1214 if (is_booting == KAL_TRUE) {
1215 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DECRYPTION_FAIL;
1216 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_DECRYPTION_FAIL, apply_filename);
1217 }
1218 MD_TRC_MCF_TR_READ_TLVOTA_FILE_DECRYPTION_FAIL(apply_filename);
1219 ret = MCF_OTA_R_DECRYPTION_FAIL;
1220
1221 return ret;
1222 }
1223 }
1224
1225 if ( (pFile->operation_mask & MCF_FILE_OP_CHECKSUM) != 0) {
1226 if (mcf_check_check_sum((kal_uint32 *)(tlvota_file->buff), pFile->file_size) != 0) {
1227 kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE);
1228 kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
1229 tlvota_file->path_type = 0;
1230 tlvota_file->last_mod_time = 0;
1231 kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t));
1232 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1233 if (is_booting == KAL_TRUE) {
1234 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_CHECKSUM_ERROR;
1235 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_CHECKSUM_ERROR, apply_filename);
1236 }
1237 MD_TRC_MCF_TR_READ_TLVOTA_FILE_CHECKSUM_ERROR(apply_filename);
1238 ret = MCF_OTA_R_CHECKSUM_ERROR;
1239
1240 return ret;
1241 }
1242 }
1243 } else {
1244 if (is_booting == KAL_TRUE) {
1245 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_INVALID_FILE;
1246 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_INVALID_FILE_VERSION, pFile->file_version);
1247 }
1248 MD_TRC_MCF_TR_READ_TLVOTA_FILE_INVALID_FILE_VERSION(apply_filename);
1249 kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE);
1250 kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
1251 tlvota_file->path_type = 0;
1252 tlvota_file->last_mod_time = 0;
1253 kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t));
1254 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1255 ret = MCF_OTA_R_INVALID_FILE;
1256
1257 return ret;
1258 }
1259
1260 tlvota_file->path_type = *apply_path_type;
1261 tlvota_file->last_mod_time = last_mod_time;
1262 tlvota_file->last_file.last_mod_time = last_mod_time;
1263
1264#if defined(__MCF_UT_FRAMEWORK_SUPPORT__)
1265 if (strcmp(tlvota_file->relative_path_name, "") == 0){
1266 strncpy(tlvota_file->relative_path_name, apply_filename, MCF_FILE_MAX_NAME_LEN - 1);
1267 }else{
1268 strncpy(apply_filename, tlvota_file->relative_path_name, MCF_FILE_MAX_NAME_LEN - 1);
1269 }
1270#else
1271 strncpy(tlvota_file->relative_path_name, apply_filename, MCF_FILE_MAX_NAME_LEN - 1);
1272#endif
1273 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1274 } else {
1275 if (is_booting == KAL_TRUE) {
1276 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_TAKE_WRITE_LOCK_FAIL;
1277 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_TAKE_WRITE_LOCK_FAIL, apply_filename, *apply_path_type, sim_id);
1278 }
1279 MD_TRC_MCF_TR_READ_TLVOTA_FILE_TAKE_WRITE_LOCK_FAIL(apply_filename, *apply_path_type, sim_id);
1280 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
1281 }
1282
1283 return ret;
1284}
1285
1286mcf_ota_result_e mcf_read_general_tlvota_file(
1287 kal_bool is_booting,
1288 kal_char *req_fs_root_path,
1289 kal_char *req_file_path_name,
1290 l4c_mcf_path_type_enum *apply_path_type,
1291 kal_char *apply_filename,
1292 mcf_t *pMcf)
1293{
1294 NVRAM_FS_PARAM_CMPT_T fs_cmpt;
1295 FS_FileDetail fs_file_detail[L4C_MCF_PATH_TYPE_MAX] = {0};
1296 kal_uint32 read_byte = 0;
1297 kal_uint32 file_size = 0;
1298 mcf_ota_result_e ret = MCF_OTA_R_SUCCESS;
1299 mcf_tlvota_file_t *tlvota_file = &(pMcf->general_tlvota_file);
1300 kal_wchar filename[MCF_FILE_MAX_MD_PATH_LEN + MCF_FILE_MAX_NAME_LEN];
1301 mcf_tool_file_info_t *pFile;
1302 kal_char password[MCF_MAX_PASSWORD_LEN] = {0};
1303 kal_bool is_default_path;
1304 kal_uint32 dummy_para;
1305 kal_int32 fs_api_ret[L4C_MCF_PATH_TYPE_MAX];
1306 kal_uint64 last_mod_time = 0;
1307 mcf_tool_gid_tlvota_file_item_t *pItem;
1308 kal_uint16 item_cnt = 0;
1309
1310 com_Mcf.is_iccid = KAL_FALSE;
1311
1312 fs_cmpt.opid_map = NVRAM_FS_CMPT_OPEN | NVRAM_FS_CMPT_GETFILESIZE | NVRAM_FS_CMPT_CLOSE;
1313 fs_cmpt.Flag = FS_READ_ONLY;
1314 fs_cmpt.Length = 0;
1315 fs_cmpt.Offset = 0;
1316 fs_cmpt.Whence = FS_FILE_BEGIN;
1317 fs_cmpt.DataPtr = &dummy_para;
1318 fs_cmpt.Read = &dummy_para;
1319 fs_cmpt.FileSize = &file_size;
1320
1321 if ( (strcmp(req_fs_root_path, "") != 0) && (strcmp(req_file_path_name, "") != 0) ) {
1322 if (strcmp(req_fs_root_path, MCF_FS_DEFAULT_FOLDER_PATH) == 0) {
1323 *apply_path_type = L4C_MCF_PATH_TYPE_OTA;
1324 } else if (strcmp(req_fs_root_path, MCF_FS_CUSTOM_FOLDER_PATH) == 0) {
1325 *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME;
1326 } else{
1327 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_INVALID_PATH(req_fs_root_path);
1328 ret = MCF_OTA_R_INVALID_PARAMETER;
1329
1330 return ret;
1331 }
1332 kal_wsprintf(filename, "%s\\%s\0", req_fs_root_path, req_file_path_name);
1333 strncpy(apply_filename, req_file_path_name, MCF_FILE_MAX_NAME_LEN - 1);
1334 is_default_path = KAL_FALSE;
1335 } else {
1336 /* Compare modified time of general OP-OTA file to select which file to be applied */
1337 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_GENERAL_TLVOTA_FILE_NAME);
1338 fs_api_ret[L4C_MCF_PATH_TYPE_OTA] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_OTA]);
1339 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_OTA, fs_api_ret[L4C_MCF_PATH_TYPE_OTA],
1340 (kal_uint32)((fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime & 0xFFFFFFFF));
1341 if (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] != FS_NO_ERROR) {
1342 kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_OTA], 0, sizeof(FS_FileDetail));
1343 }
1344
1345 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_GENERAL_TLVOTA_FILE_NAME);
1346 fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME]);
1347 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_RUNTIME, fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME],
1348 (kal_uint32)((fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime & 0xFFFFFFFF));
1349 if (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] != FS_NO_ERROR) {
1350 kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME], 0, sizeof(FS_FileDetail));
1351 }
1352
1353 if ( (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] == FS_NO_ERROR) || (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] == FS_NO_ERROR) ) {
1354 if (fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime > fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime) {
1355 *apply_path_type = L4C_MCF_PATH_TYPE_OTA;
1356 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_GENERAL_TLVOTA_FILE_NAME);
1357 } else {
1358 *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME;
1359 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_GENERAL_TLVOTA_FILE_NAME);
1360 }
1361 } else {
1362 if (is_booting == KAL_TRUE) {
1363 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL;
1364 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_COMPARE_FAIL);
1365 }
1366 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_COMPARE_FAIL();
1367 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
1368
1369 return ret;
1370 }
1371
1372 strncpy(apply_filename, MCF_FS_GENERAL_TLVOTA_FILE_NAME, MCF_FILE_MAX_NAME_LEN - 1);
1373 is_default_path = KAL_TRUE;
1374 }
1375
1376 fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt);
1377 if (fs_api_ret[0] < FS_NO_ERROR) {
1378 if (is_booting == KAL_TRUE) {
1379 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_FAIL, *apply_path_type, fs_api_ret[0]);
1380 MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename);
1381 }
1382 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_FAIL(*apply_path_type, fs_api_ret[0]);
1383 dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename);
1384
1385 /* If cannot read given TLV-OTA file, read default TLV-OTA file */
1386 if (is_default_path == KAL_FALSE) {
1387 /* Compare modified time of general OP-OTA file to select which file to be applied */
1388 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_GENERAL_TLVOTA_FILE_NAME);
1389 fs_api_ret[L4C_MCF_PATH_TYPE_OTA] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_OTA]);
1390 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_OTA, fs_api_ret[L4C_MCF_PATH_TYPE_OTA],
1391 (kal_uint32)((fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime & 0xFFFFFFFF));
1392 if (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] != FS_NO_ERROR) {
1393 kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_OTA], 0, sizeof(FS_FileDetail));
1394 }
1395
1396 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_GENERAL_TLVOTA_FILE_NAME);
1397 fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME]);
1398 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_RUNTIME, fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME],
1399 (kal_uint32)((fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime & 0xFFFFFFFF));
1400 if (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] != FS_NO_ERROR) {
1401 kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME], 0, sizeof(FS_FileDetail));
1402 }
1403
1404 if ( (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] == FS_NO_ERROR) || (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] == FS_NO_ERROR) ) {
1405 if (fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime > fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime) {
1406 *apply_path_type = L4C_MCF_PATH_TYPE_OTA;
1407 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_GENERAL_TLVOTA_FILE_NAME);
1408 } else {
1409 *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME;
1410 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_GENERAL_TLVOTA_FILE_NAME);
1411 }
1412 } else {
1413 if (is_booting == KAL_TRUE) {
1414 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL;
1415 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_COMPARE_FAIL);
1416 }
1417 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_COMPARE_FAIL();
1418 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
1419
1420 return ret;
1421 }
1422
1423 strncpy(apply_filename, MCF_FS_GENERAL_TLVOTA_FILE_NAME, MCF_FILE_MAX_NAME_LEN - 1);
1424
1425 fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt);
1426 if (fs_api_ret[0] < FS_NO_ERROR) {
1427 if (is_booting == KAL_TRUE) {
1428 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_TLVOTA_FILE_FAIL;
1429 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_FAIL, *apply_path_type, fs_api_ret[0]);
1430 MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename);
1431 }
1432 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_FAIL(*apply_path_type, fs_api_ret[0]);
1433 dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename);
1434 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
1435
1436 return ret;
1437 }
1438 } else {
1439 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
1440
1441 return ret;
1442 }
1443 }
1444
1445 if (file_size > MCF_MAX_TLVOTA_FILE_SIZE) {
1446 if (is_booting == KAL_TRUE) {
1447 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_TLVOTA_FILE_OVERSIZE;
1448 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_OVERSIZE, file_size, MCF_MAX_TLVOTA_FILE_SIZE);
1449 }
1450 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_OVERSIZE(file_size, MCF_MAX_TLVOTA_FILE_SIZE);
1451 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
1452
1453 return ret;
1454 }
1455
1456 /* Read file */
1457 fs_cmpt.opid_map = NVRAM_FS_CMPT_OPEN | NVRAM_FS_CMPT_READ | NVRAM_FS_CMPT_CLOSE;
1458 fs_cmpt.Flag = FS_READ_ONLY;
1459 fs_cmpt.Length = file_size;
1460 fs_cmpt.Offset = 0;
1461 fs_cmpt.Whence = FS_FILE_BEGIN;
1462 fs_cmpt.DataPtr = tlvota_file->buff;
1463 fs_cmpt.Read = &read_byte;
1464 fs_cmpt.FileSize = &dummy_para;
1465
1466 fs_api_ret[*apply_path_type] = FS_GetFileDetail(filename, &fs_file_detail[*apply_path_type]);
1467 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_MODIFIED_TIME(*apply_path_type, fs_api_ret[*apply_path_type],
1468 (kal_uint32)((fs_file_detail[*apply_path_type].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[*apply_path_type].LastStatusChangeTime & 0xFFFFFFFF));
1469 if (fs_api_ret[*apply_path_type] == FS_NO_ERROR) {
1470 last_mod_time = fs_file_detail[*apply_path_type].LastStatusChangeTime;
1471 } else {
1472 if (is_booting == KAL_TRUE) {
1473 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_TLVOTA_FILE_FAIL;
1474 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_FAIL, *apply_path_type, fs_api_ret[0]);
1475 MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename);
1476 }
1477 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_FAIL(*apply_path_type, fs_api_ret[*apply_path_type]);
1478 dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename);
1479 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
1480
1481 return ret;
1482 }
1483
1484 MCF_W_LOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1485 if (tlvota_file) {
1486 fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt);
1487 if (fs_api_ret[0] < FS_NO_ERROR) {
1488 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1489 if (is_booting == KAL_TRUE) {
1490 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_TLVOTA_FILE_FAIL;
1491 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_FAIL, *apply_path_type, fs_api_ret[0]);
1492 MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename);
1493 }
1494 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_FAIL(*apply_path_type, fs_api_ret[0]);
1495 dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename);
1496 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
1497
1498 return ret;
1499 }
1500
1501 com_Mcf.is_iccid = KAL_FALSE;
1502 pFile = (mcf_tool_file_info_t *)(tlvota_file->buff);
1503#ifdef __MCF_FIND_TAG_SUPPORT__
1504 if (pFile->file_version == 2 || pFile->file_version == 3) {
1505#else
1506 if (pFile->file_version == 3) {
1507#endif
1508 kal_uint32 operation_mask = 0;
1509
1510 /* Check custom operation mask */
1511 operation_mask = mcf_get_custom_operation_mask();
1512 if ((pFile->operation_mask & operation_mask) != operation_mask) {
1513 if (is_booting == KAL_TRUE) {
1514 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_OPERATION_MASK_FAIL;
1515 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_OPERATION_MASK_FAIL, apply_filename, pFile->operation_mask, operation_mask);
1516 }
1517 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_OPERATION_MASK_FAIL(apply_filename, pFile->operation_mask, operation_mask);
1518 ret = MCF_OTA_R_INVALID_FILE;
1519
1520 kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE);
1521 kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
1522 tlvota_file->path_type = 0;
1523 tlvota_file->last_mod_time = 0;
1524 kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t));
1525 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1526
1527 return ret;
1528 }
1529 /* First check digest first
1530 * If file is encrypted and has checksum.
1531 * Decrypt file before checking checksum.
1532 */
1533 // RSA verify digest
1534 if ((pFile->operation_mask & MCF_FILE_OP_SHA256_RSA2048) != 0) {
1535
1536 if (mcf_verify_digest(MCF_FILE_OP_SHA256_RSA2048, (mcf_tool_file_info_t *)(tlvota_file->buff), (mcf_digest *)(tlvota_file->buff + pFile->file_size)) != KAL_TRUE) {
1537 kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE );
1538 kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
1539 tlvota_file->path_type = 0;
1540 tlvota_file->last_mod_time = 0;
1541 kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t));
1542 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1543 if (is_booting == KAL_TRUE) {
1544 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DIGEST_FAIL;
1545 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_DIGEST_FAIL, apply_filename);
1546 }
1547 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_DIGEST_FAIL(apply_filename);
1548 ret = MCF_OTA_R_DIGEST_FAIL;
1549
1550 return ret;
1551 }
1552
1553 }
1554
1555 else if ((pFile->operation_mask & MCF_FILE_OP_SHA384_RSA3072) != 0) {
1556
1557 if (mcf_verify_digest(MCF_FILE_OP_SHA384_RSA3072, (mcf_tool_file_info_t *)(tlvota_file->buff), (mcf_digest *)(tlvota_file->buff + pFile->file_size)) != KAL_TRUE) {
1558 kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE );
1559 kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
1560 tlvota_file->path_type = 0;
1561 tlvota_file->last_mod_time = 0;
1562 kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t));
1563 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1564 if (is_booting == KAL_TRUE) {
1565 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DIGEST_FAIL;
1566 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_DIGEST_FAIL, apply_filename);
1567 }
1568 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_DIGEST_FAIL(apply_filename);
1569 ret = MCF_OTA_R_DIGEST_FAIL;
1570
1571 return ret;
1572 }
1573
1574 }
1575
1576 if ( (pFile->operation_mask & MCF_FILE_OP_AES_128) != 0) {
1577 mcf_get_custom_aes_password(password);
1578
1579 if (mcf_decrypt_128bit(password, (kal_char *)(tlvota_file->buff + pFile->total_len), (pFile->file_size - pFile->total_len) ) != KAL_TRUE) {
1580 kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE );
1581 kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
1582 tlvota_file->path_type = 0;
1583 tlvota_file->last_mod_time = 0;
1584 kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t));
1585 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1586 if (is_booting == KAL_TRUE) {
1587 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DECRYPTION_FAIL;
1588 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_DECRYPTION_FAIL, apply_filename);
1589 }
1590 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_DECRYPTION_FAIL(apply_filename);
1591 ret = MCF_OTA_R_DECRYPTION_FAIL;
1592
1593 return ret;
1594 }
1595 }
1596 else if ((pFile->operation_mask & MCF_FILE_OP_AES_256) != 0) { // for AES_256
1597 mcf_get_custom_aes_password(password);
1598
1599 if (mcf_decrypt_256bit(password, (kal_char *)(tlvota_file->buff + pFile->total_len), (pFile->file_size - pFile->total_len)) != KAL_TRUE) {
1600 kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE);
1601 kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
1602 tlvota_file->path_type = 0;
1603 tlvota_file->last_mod_time = 0;
1604 kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t));
1605 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1606 if (is_booting == KAL_TRUE) {
1607 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DECRYPTION_FAIL;
1608 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_DECRYPTION_FAIL, apply_filename);
1609 }
1610 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_DECRYPTION_FAIL(apply_filename);
1611 ret = MCF_OTA_R_DECRYPTION_FAIL;
1612
1613 return ret;
1614 }
1615 }
1616
1617 if ( (pFile->operation_mask & MCF_FILE_OP_CHECKSUM) != 0) {
1618 if (mcf_check_check_sum((kal_uint32 *)(tlvota_file->buff), pFile->file_size) != 0) {
1619 kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE);
1620 kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
1621 tlvota_file->path_type = 0;
1622 tlvota_file->last_mod_time = 0;
1623 kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t));
1624 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1625 if (is_booting == KAL_TRUE) {
1626 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_CHECKSUM_ERROR;
1627 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_CHECKSUM_ERROR, apply_filename);
1628 }
1629 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_CHECKSUM_ERROR(apply_filename);
1630 ret = MCF_OTA_R_CHECKSUM_ERROR;
1631
1632 return ret;
1633 }
1634 }
1635
1636 //Check whether general TLV-OTA have iccid tag
1637 pItem = (mcf_tool_gid_tlvota_file_item_t *)(tlvota_file->buff + pFile->total_len);
1638 while (item_cnt < pFile->item_num) {
1639 if ((pItem->tag_type == MCF_TLVOTA_TAG_ICCID)) {
1640 com_Mcf.is_iccid = KAL_TRUE;
1641 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_TAG_TYPE(MCF_TLVOTA_TAG_ICCID);
1642 break;
1643 }
1644 pItem = (mcf_tool_gid_tlvota_file_item_t *)((kal_uint8 *)pItem + pItem->total_len);
1645 item_cnt++;
1646 }
1647 } else {
1648 if (is_booting == KAL_TRUE) {
1649 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_INVALID_FILE;
1650 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_INVALID_FILE_VERSION, pFile->file_version);
1651 }
1652 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_INVALID_FILE_VERSION(pFile->file_version);
1653 kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE);
1654 kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN);
1655 tlvota_file->path_type = 0;
1656 tlvota_file->last_mod_time = 0;
1657 kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t));
1658 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1659 ret = MCF_OTA_R_INVALID_FILE;
1660
1661 return ret;
1662 }
1663
1664 tlvota_file->path_type = *apply_path_type;
1665#if defined(__MCF_UT_FRAMEWORK_SUPPORT__)
1666 if (strcmp(tlvota_file->relative_path_name, "") == 0){
1667 strncpy(tlvota_file->relative_path_name, apply_filename, MCF_FILE_MAX_NAME_LEN - 1);
1668 }else{
1669 strncpy(apply_filename, tlvota_file->relative_path_name, MCF_FILE_MAX_NAME_LEN - 1);
1670 }
1671#else
1672 strncpy(tlvota_file->relative_path_name, apply_filename, MCF_FILE_MAX_NAME_LEN - 1);
1673#endif
1674 tlvota_file->last_mod_time = last_mod_time;
1675 tlvota_file->last_file.last_mod_time = last_mod_time;
1676 MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
1677 } else {
1678 if (is_booting == KAL_TRUE) {
1679 com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_TAKE_WRITE_LOCK_FAIL;
1680 MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_TAKE_WRITE_LOCK_FAIL, apply_filename, *apply_path_type);
1681 }
1682 MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_TAKE_WRITE_LOCK_FAIL(apply_filename, *apply_path_type);
1683 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
1684 }
1685
1686
1687 return ret;
1688}
1689
1690mcf_ota_result_e mcf_read_ini_file(
1691 kal_char *req_fs_root_path,
1692 kal_char *req_file_path_name,
1693 l4c_mcf_path_type_enum *apply_path_type,
1694 kal_char *apply_filename,
1695 mcf_t *pMcf)
1696{
1697 NVRAM_FS_PARAM_CMPT_T fs_cmpt;
1698 kal_uint32 read_byte = 0;
1699 kal_uint32 file_size = 0;
1700 mcf_ota_result_e ret = MCF_OTA_R_SUCCESS;
1701 mcf_ini_file_t *ini_file = &(pMcf->ini_file);
1702 kal_wchar filename[MCF_FILE_MAX_MD_PATH_LEN + MCF_FILE_MAX_NAME_LEN];
1703 kal_bool is_default_path;
1704 kal_uint32 dummy_para;
1705 kal_int32 fs_api_ret[L4C_MCF_PATH_TYPE_MAX];
1706
1707 fs_cmpt.opid_map = NVRAM_FS_CMPT_OPEN | NVRAM_FS_CMPT_GETFILESIZE | NVRAM_FS_CMPT_CLOSE;
1708 fs_cmpt.Flag = FS_READ_ONLY;
1709 fs_cmpt.Length = 0;
1710 fs_cmpt.Offset = 0;
1711 fs_cmpt.Whence = FS_FILE_BEGIN;
1712 fs_cmpt.DataPtr = &dummy_para;
1713 fs_cmpt.Read = &dummy_para;
1714 fs_cmpt.FileSize = &file_size;
1715
1716
1717 if ( (strcmp(req_fs_root_path, "") != 0) && (strcmp(req_file_path_name, "") != 0) ) {
1718 if (strcmp(req_fs_root_path, MCF_FS_DEFAULT_FOLDER_PATH) == 0) {
1719 *apply_path_type = L4C_MCF_PATH_TYPE_OTA;
1720 } else if (strcmp(req_fs_root_path, MCF_FS_CUSTOM_FOLDER_PATH) == 0) {
1721 *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME;
1722 }
1723 kal_wsprintf(filename, "%s\\%s\0", req_fs_root_path, req_file_path_name);
1724 strncpy(apply_filename, req_file_path_name, MCF_FILE_MAX_NAME_LEN - 1);
1725 is_default_path = KAL_FALSE;
1726 } else {
1727 if (*apply_path_type == L4C_MCF_PATH_TYPE_OTA) {
1728 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, apply_filename);
1729 } else if (*apply_path_type == L4C_MCF_PATH_TYPE_RUNTIME) {
1730 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, apply_filename);
1731 }
1732 strncpy(apply_filename, MCF_FS_DEFAULT_INI_FILE_NAME, MCF_FILE_MAX_NAME_LEN - 1);
1733 is_default_path = KAL_TRUE;
1734 }
1735
1736 fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt);
1737 if (fs_api_ret[0] < FS_NO_ERROR) {
1738
1739 MD_TRC_MCF_TR_READ_INI_FILE_FAIL(*apply_path_type, fs_api_ret[0]);
1740 dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename);
1741
1742 /* If cannot read given INI file, read default INI file */
1743 if (is_default_path == KAL_FALSE) {
1744 if (*apply_path_type == L4C_MCF_PATH_TYPE_OTA) {
1745 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, apply_filename);
1746 } else if (*apply_path_type == L4C_MCF_PATH_TYPE_RUNTIME) {
1747 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, apply_filename);
1748 }
1749 strncpy(apply_filename, MCF_FS_DEFAULT_INI_FILE_NAME, MCF_FILE_MAX_NAME_LEN - 1);
1750
1751 fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt);
1752 if (fs_api_ret[0] < FS_NO_ERROR) {
1753
1754 MD_TRC_MCF_TR_READ_INI_FILE_FAIL(*apply_path_type, fs_api_ret[0]);
1755 dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename);
1756 ret = MCF_OTA_R_READ_INI_FILE_FAIL;
1757
1758 return ret;
1759 }
1760 } else {
1761 ret = MCF_OTA_R_READ_INI_FILE_FAIL;
1762
1763 return ret;
1764 }
1765 }
1766 if (file_size >= MCF_MAX_INI_FILE_SIZE-1) {
1767 MD_TRC_MCF_TR_READ_INI_FILE_OVERSIZE(file_size, MCF_MAX_INI_FILE_SIZE);
1768 ret = MCF_OTA_R_READ_INI_FILE_FAIL;
1769
1770 return ret;
1771 }
1772
1773 /* Read file */
1774 fs_cmpt.opid_map = NVRAM_FS_CMPT_OPEN | NVRAM_FS_CMPT_READ | NVRAM_FS_CMPT_CLOSE;
1775 fs_cmpt.Flag = FS_READ_ONLY;
1776 fs_cmpt.Length = file_size;
1777 fs_cmpt.Offset = 0;
1778 fs_cmpt.Whence = FS_FILE_BEGIN;
1779 fs_cmpt.DataPtr = ini_file->buff;
1780 fs_cmpt.Read = &read_byte;
1781 fs_cmpt.FileSize = &dummy_para;
1782
1783
1784 fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt);
1785 if (fs_api_ret[0] < FS_NO_ERROR) {
1786 MD_TRC_MCF_TR_READ_INI_FILE_FAIL(*apply_path_type, fs_api_ret[0]);
1787 dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename);
1788 ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
1789 return ret;
1790 }
1791
1792 if (file_size < MCF_MAX_INI_FILE_SIZE){
1793 ini_file->buff[file_size] = '\0';
1794 }
1795
1796
1797 return ret;
1798}
1799
1800kal_bool mcf_find_ini_item(kal_char* buff, kal_char *item, kal_char *value, mcf_t *pMcf)
1801{
1802 kal_bool ret = KAL_TRUE;
1803 kal_char *varstr = NULL, *substr = NULL;
1804 kal_char *saveptr = NULL;
1805 kal_char *item_ptr = NULL;
1806 kal_char *item_tag = NULL;
1807 mcf_ini_file_t *ini_file = &(pMcf->ini_file);
1808 kal_char *buffer = (kal_char *)ini_file->tmp_buff;
1809
1810
1811
1812 //buff and item cannot be NULL
1813 if(buff == NULL || item == NULL) {
1814 MD_TRC_MCF_TR_FIND_INI_ITEM_ERROR_INPUT_NULL();
1815 ret = KAL_FALSE;
1816 return ret;
1817 }
1818
1819 MD_TRC_MCF_TR_FIND_INI_ITEM_START(item);
1820
1821 /* Remove space and to uppercase */
1822 mcf_remove_spaces_and_carrier_return(buff);
1823 mcf_toupper(buff);
1824 mcf_toupper(item);
1825 mcf_remove_spaces_and_carrier_return(item);
1826
1827 kal_mem_set(buffer,0,MCF_MAX_INI_FILE_SIZE);
1828 strncpy(buffer,buff,MCF_MAX_INI_FILE_SIZE-1);
1829 buffer[MCF_MAX_INI_FILE_SIZE-1] = '\0';
1830
1831
1832 item_ptr = strstr (buffer,item);
1833 if (item_ptr != 0) {
1834 item_tag = kal_strtok_r(item_ptr,"=",&saveptr);
1835 substr = kal_strtok_r(NULL,"=",&saveptr);
1836 if (item_tag != 0) {
1837 if (strcmp(item_tag,item) == 0){
1838 if (substr != NULL){
1839 varstr = strstr(substr,"\n");
1840 if (varstr == NULL){
1841 if (strlen(substr) > MCF_MAX_INI_ITEM_VALUE_LEN-1){
1842 memset(value, 0, MCF_MAX_INI_ITEM_VALUE_LEN);
1843 strncpy(value, substr, MCF_MAX_INI_ITEM_VALUE_LEN);
1844 }else{
1845 memset(value, 0, MCF_MAX_INI_ITEM_VALUE_LEN);
1846 strncpy(value, substr, strlen(substr));
1847 }
1848
1849 }else{
1850 if (strlen(substr)-strlen(varstr) + 1 > MCF_MAX_INI_ITEM_VALUE_LEN-1){
1851 memset(value, 0, MCF_MAX_INI_ITEM_VALUE_LEN);
1852 strncpy(value, substr, MCF_MAX_INI_ITEM_VALUE_LEN);
1853 }else{
1854 memset(value, 0, MCF_MAX_INI_ITEM_VALUE_LEN);
1855 strncpy(value, substr, strlen(substr)-strlen(varstr));
1856 }
1857
1858
1859 }
1860 }else{
1861 value = NULL;
1862 MD_TRC_MCF_TR_FIND_INI_ITEM_ERROR_CAN_NOT_FIND_ITEM();
1863 ret = KAL_FALSE;
1864 return ret;
1865 }
1866 }else{
1867 value = NULL;
1868 MD_TRC_MCF_TR_FIND_INI_ITEM_ERROR_ITEM_LENGTH();
1869 ret = KAL_FALSE;
1870 return ret;
1871 }
1872
1873 } else {
1874 value = NULL;
1875 MD_TRC_MCF_TR_FIND_INI_ITEM_ERROR_CAN_NOT_FIND_ITEM();
1876 ret = KAL_FALSE;
1877 return ret;
1878 }
1879 } else {
1880 value = NULL;
1881 MD_TRC_MCF_TR_FIND_INI_ITEM_ERROR_CAN_NOT_FIND_ITEM();
1882 ret = KAL_FALSE;
1883 return ret;
1884 }
1885
1886
1887
1888 MD_TRC_MCF_TR_FIND_INI_ITEM_RETURN_VALUE(item, value);
1889
1890 return ret;
1891}
1892
1893kal_bool mcf_find_ini_sbp_id(kal_char *tag_str, kal_uint32 *sbp_id, kal_uint16 *sbp_id_num, kal_bool *general)
1894{
1895 kal_uint16 i = 0;
1896 kal_bool ret = KAL_TRUE;
1897 kal_char *saveptr = NULL, *varstr = NULL, *substr = NULL, *tmpstr = NULL;
1898 kal_char *sbp_id_tag[MCF_MAX_TAG_NUM];
1899 kal_uint16 tag_cnt = 0;
1900 kal_char *tag[MCF_MAX_TAG_NUM];
1901 kal_uint16 tag_num = 0;
1902
1903 MD_TRC_MCF_TR_FIND_INI_SBP_ID_START(tag_str);
1904
1905 //buff and item cannot be NULL
1906 if(tag_str == NULL) {
1907 MD_TRC_MCF_TR_FIND_INI_SBP_ID_ERROR_INPUT_NULL();
1908 ret = KAL_FALSE;
1909 return ret;
1910 }
1911
1912
1913 //Split ',' from tag
1914 substr = kal_strtok_r(tag_str, ",", &saveptr);
1915
1916 if (substr == NULL){
1917 MD_TRC_MCF_TR_FIND_INI_SBP_ID_ERROR_CAN_NOT_FIND_ITEM();
1918 ret = KAL_FALSE;
1919 return ret;
1920 }
1921
1922
1923 while(substr != NULL){
1924 tag[tag_cnt] = substr;
1925 tag_cnt++;
1926 substr = kal_strtok_r(NULL, ",",&saveptr);
1927 }
1928
1929
1930
1931 /* ICCID case should apply general tlvota*/
1932 tmpstr = strstr(tag[0], "_");
1933 if (tmpstr == NULL){
1934 *general = KAL_TRUE;
1935 MD_TRC_MCF_TR_FIND_INI_SBP_ID_ICCID_USIR(tag[0]);
1936 }
1937
1938 //Split '_' from SBPID_MNC_MCC tag
1939 sbp_id_tag[0] = kal_strtok_r(tag[0], "_", &saveptr);
1940
1941 if (strcmp(sbp_id_tag[0],"") == 0){
1942 MD_TRC_MCF_TR_FIND_INI_SBP_ID_ERROR_CAN_NOT_FIND_ITEM();
1943 }
1944
1945
1946 /* NA case should apply general tlvota */
1947 if (strcmp(sbp_id_tag[0],"NA") == 0){
1948 *general = KAL_TRUE;
1949 MD_TRC_MCF_TR_FIND_INI_SBP_ID_NA(*general);
1950 }
1951
1952 for (i = 1; i < tag_cnt; i++){
1953
1954 tmpstr = strstr(tag[i], "_");
1955 if (tmpstr == NULL){
1956 *general = KAL_TRUE;
1957 if(i+1 < tag_cnt){
1958 i++;
1959 }
1960 }else{
1961 varstr = kal_strtok_r(tag[i], "_",&saveptr);
1962 if(varstr == NULL){
1963 *general = KAL_TRUE;
1964 if(i+1 < tag_cnt){
1965 i++;
1966 }
1967 }else{
1968 if(strcmp(varstr,"NA") == 0){
1969 *general = KAL_TRUE;
1970 if(i+1 < tag_cnt){
1971 i++;
1972 }
1973 }
1974 if (strcmp(varstr,sbp_id_tag[tag_num]) != 0){
1975 //save different sbp_id
1976 tag_num++;
1977 sbp_id_tag[tag_num] = varstr;
1978 }
1979 }
1980 }
1981 }
1982
1983 for (i = 0; i < tag_num + 1; i++){
1984 sbp_id[i] = mcf_atoi(sbp_id_tag[i]);
1985 }
1986
1987
1988
1989 *sbp_id_num = tag_num + 1;
1990
1991 MD_TRC_MCF_TR_FIND_INI_SBP_ID_RETURN_NUM(*sbp_id_num);
1992
1993 return ret;
1994}
1995
1996kal_bool mcf_compose_ini_item(kal_char *orig_buff, kal_char *new_buff, kal_char *item, kal_char *orig_value, kal_char *value)
1997{
1998 kal_bool ret = KAL_TRUE;
1999 kal_char *tmpstr = NULL, *varstr = NULL, *substr = NULL;
2000 kal_uint32 len = 0;
2001
2002 MD_TRC_MCF_TR_COMPOSE_INI_ITEM_START(item, orig_value);
2003
2004 mcf_remove_spaces_and_carrier_return(orig_buff);
2005 mcf_remove_spaces_and_carrier_return(item);
2006 kal_mem_set(new_buff, 0, MCF_MAX_INI_FILE_SIZE);
2007
2008 substr = strstr (orig_buff,"\0");
2009 if (substr != NULL){
2010 len = strlen(orig_buff);
2011 }else{
2012 MD_TRC_MCF_TR_COMPOSE_INI_ITEM_INVALID_BUFF();
2013 ret = KAL_FALSE;
2014 return ret;
2015 }
2016
2017
2018
2019 substr = strstr (orig_buff,item);
2020 if (substr != NULL){
2021 varstr = strstr(substr,"=");
2022 if (varstr != NULL){
2023 if (strlen(substr)-strlen(varstr) == strlen(item)){
2024 if(strcmp(orig_value,"") != 0){
2025 tmpstr = strstr(substr,orig_value);
2026 if (tmpstr != NULL){
2027 if ((len-strlen(varstr)+4+strlen(value)+strlen(tmpstr)-strlen(orig_value)) >= MCF_MAX_INI_FILE_SIZE){
2028 MD_TRC_MCF_TR_COMPOSE_INI_ITEM_INVALID_BUFF_LENGTH();
2029 ret = KAL_FALSE;
2030 return ret;
2031 }
2032 strncpy(new_buff,orig_buff,len-strlen(varstr));
2033 strncat (new_buff,"=", MCF_MAX_INI_FILE_SIZE - 1);
2034 strncat (new_buff,value, MCF_MAX_INI_FILE_SIZE - 1);
2035 strncat (new_buff,tmpstr+strlen(orig_value), MCF_MAX_INI_FILE_SIZE - 1);
2036 strncat (new_buff,"\n\0", MCF_MAX_INI_FILE_SIZE - 1);
2037 }else{
2038 MD_TRC_MCF_TR_COMPOSE_INI_ITEM_INVALID_ORIGINAL_VALUE(orig_value);
2039 ret = KAL_FALSE;
2040 return ret;
2041 }
2042 }else{
2043 if ((len-strlen(varstr)+4+strlen(value)+strlen(substr)-strlen(item)) >= MCF_MAX_INI_FILE_SIZE){
2044 MD_TRC_MCF_TR_COMPOSE_INI_ITEM_INVALID_BUFF_LENGTH();
2045 ret = KAL_FALSE;
2046 return ret;
2047 }
2048 strncpy(new_buff,orig_buff,len-strlen(varstr));
2049 strncat (new_buff,"=", MCF_MAX_INI_FILE_SIZE - 1);
2050 strncat (new_buff,value, MCF_MAX_INI_FILE_SIZE - 1);
2051 strncat (new_buff,"\n", MCF_MAX_INI_FILE_SIZE - 1);
2052 strncat (new_buff,substr+strlen(item)+1, MCF_MAX_INI_FILE_SIZE - 1);
2053 strncat (new_buff,"\n\0", MCF_MAX_INI_FILE_SIZE - 1);
2054 }
2055 }else{
2056 MD_TRC_MCF_TR_COMPOSE_INI_ITEM_ERROR_ITEM_LENGTH();
2057 ret = KAL_FALSE;
2058 return ret;
2059
2060 }
2061 }else{
2062 tmpstr = strstr(substr,orig_value);
2063 if (tmpstr != NULL){
2064 if ((len+4+strlen(value)+strlen(tmpstr)-strlen(orig_value)) >= MCF_MAX_INI_FILE_SIZE){
2065 MD_TRC_MCF_TR_COMPOSE_INI_ITEM_INVALID_BUFF_LENGTH();
2066 ret = KAL_FALSE;
2067 return ret;
2068 }
2069 strncpy(new_buff,orig_buff,len);
2070 strncat (new_buff,"=", MCF_MAX_INI_FILE_SIZE - 1);
2071 strncat (new_buff,value, MCF_MAX_INI_FILE_SIZE - 1);
2072 strncat (new_buff,tmpstr+strlen(orig_value), MCF_MAX_INI_FILE_SIZE - 1);
2073 strncat (new_buff,"\n\0", MCF_MAX_INI_FILE_SIZE - 1);
2074 }else{
2075 MD_TRC_MCF_TR_COMPOSE_INI_ITEM_INVALID_ORIGINAL_VALUE(orig_value);
2076 ret = KAL_FALSE;
2077 return ret;
2078 }
2079 }
2080
2081
2082 }
2083 else{
2084 //new item
2085 if ((len+5+strlen(item)+strlen(value)) >= MCF_MAX_INI_FILE_SIZE){
2086 MD_TRC_MCF_TR_COMPOSE_INI_ITEM_INVALID_BUFF_LENGTH();
2087 ret = KAL_FALSE;
2088 return ret;
2089 }
2090 strncpy(new_buff,orig_buff, MCF_MAX_INI_FILE_SIZE - 1);
2091 strncat(new_buff,"\n", MCF_MAX_INI_FILE_SIZE - 1);
2092 strncat(new_buff,item, MCF_MAX_INI_FILE_SIZE - 1);
2093 strncat(new_buff,"=", MCF_MAX_INI_FILE_SIZE - 1);
2094 strncat(new_buff,value, MCF_MAX_INI_FILE_SIZE - 1);
2095 strncat (new_buff,"\n\0", MCF_MAX_INI_FILE_SIZE - 1);
2096 }
2097
2098
2099 return ret;
2100}
2101
2102void mcf_dump_data(kal_bool is_booting, void *p_data, kal_uint32 len)
2103{
2104 kal_uint32 i = 0;
2105 kal_uint32 buff;
2106
2107 for (i = 0; len > 0; i++){
2108 if (len >= 4) {
2109 buff = 0;
2110 kal_mem_cpy(&buff, (kal_uint8 *)p_data + (i * 4), 4);
2111 len -= 4;
2112 } else {
2113 buff = 0;
2114 kal_mem_cpy(&buff, (kal_uint8 *)p_data + (i * 4), len);
2115 len = 0;
2116 }
2117
2118 if (is_booting == KAL_TRUE) {
2119 MCF_BOOT_TRACE(MCF_BOOT_TR_DATA_DUMP_TRACE, i, buff);
2120 }
2121 MD_TRC_MCF_TR_DATA_DUMP_TRACE(i, buff);
2122 }
2123}
2124
2125#define GUARD_PARRTEN 0xAABBCCDD
2126#define FULL_PARRTEN 0xAABBFFFF
2127void mcf_write_boot_trace(kal_uint32 trace_enum, ...)
2128{
2129 va_list ap;
2130 kal_uint32 i = 0;
2131 kal_uint32 *value= NULL;
2132 char *substr = NULL;
2133 // store into com_Mcf.boot_trace_buff
2134 // enum, num, type, size, value, type, size, value
2135 // enum, num, type, size, value, type, size, value
2136 // enum, num, type, size, value, type, size, value
2137 mcf_boot_trace_struct *trace_ptr = (mcf_boot_trace_struct *)com_Mcf.boot_trace_buff_ptr;
2138 mcf_boot_trace_value_struct *value_ptr = NULL;
2139
2140 if(com_Mcf.boot_trace_buff_ptr == NULL ){
2141 com_Mcf.boot_trace_buff_ptr = (kal_uint32 *)com_Mcf.boot_trace_buff;
2142 trace_ptr = (mcf_boot_trace_struct *)com_Mcf.boot_trace_buff_ptr;
2143 }
2144
2145 value_ptr = &trace_ptr->value_ptr;
2146
2147 if((char *)trace_ptr + 512 > (char *)com_Mcf.boot_trace_buff + sizeof(com_Mcf.boot_trace_buff))
2148 {
2149 if(com_Mcf.boot_trace_full == 1) return;
2150 com_Mcf.boot_trace_full = 1;
2151 trace_ptr->guard_pattern = GUARD_PARRTEN;
2152 trace_ptr->trace_enum = FULL_PARRTEN;
2153 com_Mcf.boot_trace_buff_ptr = (kal_uint32 *)(trace_ptr+1);
2154 return;
2155 }
2156
2157 trace_ptr->guard_pattern = GUARD_PARRTEN;
2158 trace_ptr->trace_enum = trace_enum;
2159
2160 substr = strstr(boot_trace_format[trace_enum].log_format, "%");
2161 va_start(ap, trace_enum);
2162 while ( (kal_uint32)(value = (kal_uint32 *)va_arg(ap,void *)) != END_PATTERN)
2163 {
2164 if(substr == NULL) break;
2165
2166 switch(*(substr + 1))
2167 {
2168 case 's':
2169 {
2170 char *string_ptr = (char *)value;
2171 value_ptr->size = strlen(string_ptr);
2172 kal_mem_cpy(&value_ptr->type_u.string, string_ptr, value_ptr->size + 1);
2173 value_ptr->size = ((value_ptr->size + 4) >> 2 ) << 2 ; // size pedding to 4 byte alignment
2174 value_ptr->type = MCF_TYPE_STRING;
2175 }
2176 break;
2177 default:
2178 {
2179 value_ptr->size = sizeof(kal_uint32);
2180 value_ptr->type_u.integer = (kal_uint32)value;
2181 value_ptr->type = MCF_TYPE_INTEGER;
2182 }
2183 break;
2184 }
2185
2186 i++;
2187 value_ptr = (mcf_boot_trace_value_struct *)((kal_uint8 *)&value_ptr->type_u.value + value_ptr->size);
2188
2189 substr = strstr(substr + 1, "%");
2190 }
2191 va_end(ap);
2192
2193 trace_ptr->total_num = i;
2194
2195 if(trace_ptr->total_num == 0 ) com_Mcf.boot_trace_buff_ptr = (kal_uint32 *)(trace_ptr+1);
2196 else com_Mcf.boot_trace_buff_ptr = (kal_uint32 *)value_ptr;
2197}
2198
2199void mcf_dump_boot_trace(void)
2200{
2201 mcf_boot_trace_struct *trace_ptr = (mcf_boot_trace_struct *)com_Mcf.boot_trace_buff;
2202 kal_uint32 i = 0;
2203 mcf_boot_trace_value_struct value_list[7]; // max DHL arg is 7
2204 mcf_boot_trace_value_struct *current_value;
2205
2206 while ((char *)trace_ptr < (char *)com_Mcf.boot_trace_buff_ptr)
2207 {
2208 ASSERT(trace_ptr->guard_pattern == GUARD_PARRTEN);
2209 current_value = &trace_ptr->value_ptr;
2210
2211 if(trace_ptr->trace_enum == FULL_PARRTEN)
2212 {
2213 MCF_BOOT_PRINT("[MCF] boot trace buffer full!!!");
2214 break;
2215 }
2216
2217 for(i = 0 ; i < trace_ptr->total_num ; i++)
2218 {
2219 value_list[i].size = current_value->size;
2220 switch(current_value->type)
2221 {
2222 case MCF_TYPE_INTEGER:
2223 value_list[i].type_u.value = current_value->type_u.integer;
2224 break;
2225 case MCF_TYPE_STRING:
2226 value_list[i].type_u.value = (kal_uint32)&current_value->type_u.string;
2227 break;
2228 default:
2229 break;
2230 }
2231 current_value = (mcf_boot_trace_value_struct *)((kal_uint8 *)&current_value->type_u.value + current_value->size);
2232 }
2233 switch(trace_ptr->total_num)
2234 {
2235 case 0:
2236 MCF_BOOT_PRINT(boot_trace_format[trace_ptr->trace_enum].log_format);
2237 break;
2238 case 1:
2239 MCF_BOOT_PRINT(boot_trace_format[trace_ptr->trace_enum].log_format, value_list[0].type_u.value);
2240 break;
2241 case 2:
2242 MCF_BOOT_PRINT(boot_trace_format[trace_ptr->trace_enum].log_format, value_list[0].type_u.value, value_list[1].type_u.value);
2243 break;
2244 case 3:
2245 MCF_BOOT_PRINT(boot_trace_format[trace_ptr->trace_enum].log_format, value_list[0].type_u.value, value_list[1].type_u.value, value_list[2].type_u.value);
2246 break;
2247 case 4:
2248 MCF_BOOT_PRINT(boot_trace_format[trace_ptr->trace_enum].log_format, value_list[0].type_u.value, value_list[1].type_u.value, value_list[2].type_u.value, value_list[3].type_u.value);
2249 break;
2250 case 5:
2251 MCF_BOOT_PRINT(boot_trace_format[trace_ptr->trace_enum].log_format, value_list[0].type_u.value, value_list[1].type_u.value, value_list[2].type_u.value, value_list[3].type_u.value, value_list[4].type_u.value);
2252 break;
2253 case 6:
2254 MCF_BOOT_PRINT(boot_trace_format[trace_ptr->trace_enum].log_format, value_list[0].type_u.value, value_list[1].type_u.value, value_list[2].type_u.value, value_list[3].type_u.value, value_list[4].type_u.value, value_list[5].type_u.value);
2255 break;
2256 case 7:
2257 MCF_BOOT_PRINT(boot_trace_format[trace_ptr->trace_enum].log_format, value_list[0].type_u.value, value_list[1].type_u.value, value_list[2].type_u.value, value_list[3].type_u.value, value_list[4].type_u.value, value_list[5].type_u.value, value_list[6].type_u.value);
2258 break;
2259 }
2260
2261 if(trace_ptr->total_num == 0) trace_ptr++;
2262 else trace_ptr = (mcf_boot_trace_struct *)current_value;
2263 }
2264}
2265
2266mcf_ota_result_e mcf_write_buffer(
2267 kal_char *folder_path,
2268 kal_char *file_name,
2269 kal_uint8 *buffer,
2270 kal_uint32 total_size)
2271{
2272 mcf_ota_result_e mcf_ret = MCF_OTA_R_SUCCESS;
2273#if defined(__MTK_TARGET__)
2274 kal_wchar file_path_name[MCF_FILE_MAX_MD_PATH_LEN * 2];
2275 FS_HANDLE file_handle;
2276 kal_uint32 len = 0;
2277 kal_int32 ret = FS_NO_ERROR;
2278
2279 MD_TRC_MCF_TR_WRITE_BUFFER_START(file_name, folder_path, total_size);
2280
2281 kal_wsprintf(file_path_name, "%s\\%s\0", folder_path, file_name);
2282 file_handle = FS_Open(file_path_name, FS_CREATE | FS_READ_WRITE | FS_OPEN_NO_DIR);
2283
2284 ret = FS_Write(file_handle, buffer, total_size, &len);
2285 if (ret != FS_NO_ERROR) {
2286 MD_TRC_MCF_TR_WRITE_BUFFER_FAIL(file_handle, ret);
2287 mcf_ret = MCF_OTA_R_WRITE_DISK_FAIL;
2288 }
2289
2290 FS_Close(file_handle);
2291#endif
2292 return mcf_ret;
2293}
2294
2295mcf_ota_result_e mcf_get_file_last_mod_time(
2296 kal_char *apply_filename,
2297 l4c_mcf_path_type_enum apply_path_type,
2298 kal_uint64 *last_mod_time)
2299{
2300 mcf_ota_result_e mcf_ret = MCF_OTA_R_SUCCESS;
2301 kal_wchar filename[MCF_FILE_MAX_MD_PATH_LEN + MCF_FILE_MAX_NAME_LEN];
2302 FS_FileDetail fs_file_detail[L4C_MCF_PATH_TYPE_MAX] = {0};
2303 kal_int32 fs_api_ret[L4C_MCF_PATH_TYPE_MAX];
2304
2305 MD_TRC_MCF_TR_GET_FILE_LAST_MOD_TIME_START(apply_filename, apply_path_type);
2306 if (apply_path_type == L4C_MCF_PATH_TYPE_OTA){
2307 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, apply_filename);
2308 }else if(apply_path_type == L4C_MCF_PATH_TYPE_RUNTIME){
2309 kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, apply_filename);
2310 }else{
2311 *last_mod_time = 0;
2312 MD_TRC_MCF_TR_GET_FILE_LAST_MOD_TIME_INVALID_PATH_TYPE(apply_path_type);
2313 mcf_ret = MCF_OTA_R_INVALID_PARAMETER;
2314 return mcf_ret;
2315 }
2316 fs_api_ret[apply_path_type] = FS_GetFileDetail(filename, &fs_file_detail[apply_path_type]);
2317 MD_TRC_MCF_TR_GET_FILE_LAST_MOD_TIME(apply_path_type, fs_api_ret[apply_path_type],
2318 (kal_uint32)((fs_file_detail[apply_path_type].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[apply_path_type].LastStatusChangeTime & 0xFFFFFFFF));
2319 if (fs_api_ret[apply_path_type] == FS_NO_ERROR) {
2320 *last_mod_time = fs_file_detail[apply_path_type].LastStatusChangeTime;
2321 } else {
2322 *last_mod_time = 0;
2323 MD_TRC_MCF_TR_GET_FILE_LAST_MOD_TIME_FAIL(L4C_MCF_PATH_TYPE_OTA, fs_api_ret[L4C_MCF_PATH_TYPE_OTA]);
2324 mcf_ret = MCF_OTA_R_READ_OTA_FILE_FAIL;
2325 return mcf_ret;
2326 }
2327
2328 return mcf_ret;
2329}
2330
2331void mcf_dump_important_info(void)
2332{
2333 mcf_t *pMcf = mcf_get_instance();
2334 mcf_ota_file_t *ota_file = &(pMcf->ota_file);
2335 mcf_tlvota_file_t *tlvota_file;
2336 kal_uint8 path_type;
2337 kal_char relative_path_name[MCF_FILE_MAX_NAME_LEN];
2338 kal_uint8 i = 0;
2339
2340 MCF_R_LOCK_OBJECT(ota_file, mcf_enhmutex_g);
2341 if (ota_file) {
2342 path_type = ota_file->path_type;
2343 strncpy(relative_path_name, ota_file->relative_path_name, MCF_FILE_MAX_NAME_LEN - 1);
2344 MD_TRC_MCF_TR_DUMP_IMPORTANT_INFO_OTA_FILE(path_type, relative_path_name);
2345 MCF_R_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g);
2346 } else {
2347 MD_TRC_MCF_TR_DUMP_IMPORTANT_INFO_TAKE_READ_LOCK_FAIL();
2348 }
2349
2350 for (i = 0; i < MAX_SIM_NUM; i++) {
2351 tlvota_file = &(pMcf->tlvota_file[i]);
2352 MCF_R_LOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
2353 if (tlvota_file) {
2354 path_type = tlvota_file->path_type;
2355 strncpy(relative_path_name, tlvota_file->relative_path_name, MCF_FILE_MAX_NAME_LEN - 1);
2356 MD_TRC_MCF_TR_DUMP_IMPORTANT_INFO_TLVOTA_FILE(i, path_type, relative_path_name);
2357 MCF_R_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
2358 } else {
2359 MD_TRC_MCF_TR_DUMP_IMPORTANT_INFO_TAKE_READ_LOCK_FAIL();
2360 }
2361 }
2362
2363 tlvota_file = &(pMcf->general_tlvota_file);
2364 MCF_R_LOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
2365 if (tlvota_file) {
2366 path_type = tlvota_file->path_type;
2367 strncpy(relative_path_name, tlvota_file->relative_path_name, MCF_FILE_MAX_NAME_LEN - 1);
2368 MD_TRC_MCF_TR_DUMP_IMPORTANT_INFO_GENERAL_TLVOTA_FILE(path_type, relative_path_name);
2369 MCF_R_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g);
2370 } else {
2371 MD_TRC_MCF_TR_DUMP_IMPORTANT_INFO_TAKE_READ_LOCK_FAIL();
2372 }
2373
2374}
2375
2376kal_int32 mcf_atoi(const void *src)
2377{
2378 kal_int32 res=0;
2379 kal_int8 *p_src=(kal_int8*)src;
2380
2381 while( *p_src>='0' && *p_src<='9' ){
2382 res = res*10 + (*p_src - '0');
2383 p_src++;
2384 }
2385
2386 return res;
2387}
2388
2389kal_int32 mcf_str_strcmp(const void *str1, const void *str2)
2390{
2391 kal_int8 *p_str1=(kal_int8*)str1, *p_str2=(kal_int8*)str2;
2392
2393 if( p_str1==NULL || p_str2==NULL ){
2394 return 1;
2395 }
2396
2397 while(*p_str1==*p_str2 && *p_str1!='\0'){
2398 p_str1++;
2399 p_str2++;
2400 }
2401 return *p_str1 - *p_str2;
2402}
2403
2404void mcf_remove_spaces_and_carrier_return(kal_char* src)
2405{
2406 kal_char* str1 = src;
2407 kal_char* str2 = src;
2408 while(*str2 != 0)
2409 {
2410
2411 *str1 = *str2++;
2412
2413 /* 32 = space, 13 = "\r" */
2414 /* Windows uses \r\n to a new line, Linux uses \n to a new line */
2415
2416 if(*str1 != 32 && *str1 != 13){
2417 str1++;
2418 }
2419 }
2420 *str1 = 0;
2421
2422}
2423
2424void mcf_toupper(kal_char* src)
2425{
2426 kal_uint32 k = 0;
2427 while(src[k] != 0)
2428 {
2429 if(src[k] >= 'a' && src[k] <= 'z'){
2430 src[k] = src[k]-32;
2431 }
2432 k++;
2433 }
2434
2435}
2436
2437kal_int32 mcf_str_strlen(const void *src)
2438{
2439 kal_int8 *p_src=(kal_int8*)src;
2440 kal_int32 len=0;
2441
2442 if( p_src==NULL ){
2443 return 0;
2444 }
2445
2446 while('\0' != *p_src){
2447 len++;
2448 p_src++;
2449 }
2450 return len;
2451}
2452
2453kal_bool mcf_hex_str_reverse(kal_char *str, kal_uint32 length)
2454{
2455 kal_char temp1;
2456 kal_char temp2;
2457 kal_uint32 i;
2458
2459 if(str == NULL || length < 0 || length %2 != 0){
2460 return KAL_FALSE;
2461 }
2462
2463 if(length < 4){
2464 return KAL_TRUE;
2465 }
2466
2467 for(i = 0; i < length/2; i+=2){
2468 temp1 = str[i];
2469 str[i] = str[length-2-i];
2470 str[length-2-i] = temp1;
2471
2472 temp2 = str[i+1];
2473 str[i+1] = str[length-1-i];
2474 str[length-1-i] = temp2;
2475 }
2476
2477 return KAL_TRUE;
2478}
2479
2480kal_int16 mcf_binary_search_lid(kal_uint16 find_lid, kal_uint16 *lid_arr, kal_uint16 lid_size, kal_uint16 *new_pos)
2481{
2482 kal_int16 first = 0, // First array element
2483 last = lid_size - 1, // Last array element
2484 middle = 0, // Mid point of search
2485 position = -1; // Position of search value
2486 kal_bool found = KAL_FALSE; // Flag
2487
2488 while (!found && first <= last)
2489 {
2490 middle = (first + last) / 2; // Calculate mid point
2491 if(middle < 0)
2492 return -1;
2493 if (lid_arr[middle] == find_lid) // If value is found at mid
2494 {
2495 found = KAL_TRUE;
2496 position = middle;
2497 }
2498 else if (lid_arr[middle] > find_lid){ // If value is in lower half
2499 last = middle - 1;
2500 *new_pos = middle;
2501 }
2502 else{
2503 first = middle + 1; // If value is in upper half
2504 *new_pos = first;
2505 }
2506 }
2507 if(lid_size == 0){
2508 *new_pos = 0;
2509 }
2510
2511
2512 return position;
2513}
2514
2515kal_bool mcf_insert_lid(kal_uint16 new_lid, kal_uint16 *lid_arr, kal_uint16 lid_size, kal_uint16 new_pos)
2516{
2517 kal_bool ret = KAL_TRUE;
2518 kal_uint16 i = 0;
2519 if (lid_size >= NVRAM_MCF_SAVE_LAST_LID_CNT){
2520 ret = KAL_FALSE;
2521 return ret;
2522 }
2523
2524 for(i = lid_size; i > new_pos; i--){
2525 lid_arr[i] = lid_arr[i-1];
2526 }
2527 lid_arr[new_pos] = new_lid;
2528
2529 return ret;
2530}
2531
2532#ifdef __MCF_COMBINE_FILE_SUPPORT__
2533kal_int16 mcf_binary_search_lid_struct(kal_uint16 find_lid, nvram_mcf_lid_config_struct *lid_conf, kal_uint16 lid_size, kal_uint16 *new_pos)
2534{
2535 kal_int16 first = 0, // First array element
2536 last = lid_size - 1, // Last array element
2537 middle = 0, // Mid point of search
2538 position = -1; // Position of search value
2539 kal_bool found = KAL_FALSE; // Flag
2540
2541 while (!found && first <= last)
2542 {
2543 middle = (first + last) / 2; // Calculate mid point
2544 if(middle < 0)
2545 return -1;
2546 if (lid_conf[middle].lid == find_lid) // If value is found at mid
2547 {
2548 found = KAL_TRUE;
2549 position = middle;
2550 }
2551 else if (lid_conf[middle].lid > find_lid){ // If value is in lower half
2552 last = middle - 1;
2553 *new_pos = middle;
2554 }
2555 else{
2556 first = middle + 1; // If value is in upper half
2557 *new_pos = first;
2558 }
2559 }
2560 if(lid_size == 0){
2561 *new_pos = 0;
2562 }
2563
2564
2565 return position;
2566}
2567
2568kal_bool mcf_insert_lid_struct(kal_uint16 new_lid, nvram_mcf_lid_config_struct *lid_conf, kal_uint16 lid_size, kal_uint16 new_pos, kal_bool not_reset, kal_bool set_combined)
2569{
2570 kal_bool ret = KAL_TRUE;
2571 kal_uint16 i = 0;
2572 if (lid_size >= NVRAM_MCF_SAVE_LAST_LID_CNT){
2573 ret = KAL_FALSE;
2574 return ret;
2575 }
2576
2577 for(i = lid_size; i > new_pos; i--){
2578 kal_mem_cpy(&lid_conf[i], &lid_conf[i-1], sizeof(nvram_mcf_lid_config_struct));
2579 }
2580 lid_conf[new_pos].lid = new_lid;
2581 lid_conf[new_pos].not_reset = not_reset;
2582 lid_conf[new_pos].set_combined = set_combined;
2583
2584 return ret;
2585}
2586
2587kal_bool mcf_clear_last_modified_lid(nvram_mcf_lid_config_struct *lid_conf, kal_uint16 *lid_size)
2588{
2589 kal_bool ret = KAL_TRUE;
2590 kal_uint16 i = 0;
2591 kal_uint16 index = 0;
2592 kal_uint16 lid_cnt = 0;
2593 kal_uint16 total_cnt = 0;
2594
2595 lid_cnt = *lid_size;
2596
2597 if (lid_cnt >= NVRAM_MCF_SAVE_LAST_LID_CNT){
2598 ret = KAL_FALSE;
2599 return ret;
2600 }
2601
2602 for(i = 0; i < lid_cnt; i++){
2603
2604 if(lid_conf[i].set_combined == KAL_TRUE ){
2605 kal_mem_set(&lid_conf[i], 0, sizeof(nvram_mcf_lid_config_struct));
2606 index++;
2607 while(index < lid_cnt && lid_conf[index].set_combined == KAL_TRUE){
2608 kal_mem_set(&lid_conf[index], 0, sizeof(nvram_mcf_lid_config_struct));
2609 index++;
2610 }
2611 }
2612
2613 if (index < lid_cnt && i != index){
2614 kal_mem_cpy(&lid_conf[i], &lid_conf[index], sizeof(nvram_mcf_lid_config_struct));
2615 kal_mem_set(&lid_conf[index], 0, sizeof(nvram_mcf_lid_config_struct));
2616 total_cnt++;
2617 }else if(i == index){
2618 total_cnt++;
2619 }
2620
2621 index ++;
2622
2623 }
2624
2625 *lid_size = total_cnt;
2626
2627
2628 return ret;
2629}
2630#endif
2631
2632kal_int8* mcf_bytes_to_hex(const void *bytes, kal_int32 length, kal_bool upperCase, void *hex)
2633{
2634 kal_int8 *p_hex=(kal_int8*)hex, *p_bytes=(kal_int8*)bytes;
2635 kal_int8 LCaseHexArray[] = "0123456789abcdef";
2636 kal_int8 UCaseHexArray[] = "0123456789ABCDEF";
2637 kal_uint32 i=0, v=0;
2638 kal_mem_set(p_hex, 0, length*2 + 1);
2639
2640 if (p_bytes == NULL) {
2641 return NULL;
2642 }
2643
2644 for (i=0; i<length; i++) {
2645 v=p_bytes[i]&0xFF;
2646 if( v<0 || (v>>4)>=sizeof(LCaseHexArray) || (v&0x0F)>=sizeof(LCaseHexArray) || (v>>4) < 0 || (v&0x0F) < 0){
2647 return NULL;
2648 } else if( upperCase ){
2649 p_hex[i*2] = UCaseHexArray[v >> 4];
2650 p_hex[i*2 + 1] = UCaseHexArray[v & 0x0F];
2651 } else{
2652 p_hex[i*2] = LCaseHexArray[v >> 4];
2653 p_hex[i*2 + 1] = LCaseHexArray[v & 0x0F];
2654 }
2655
2656 }
2657 return p_hex;
2658}
2659
2660kal_int8* mcf_hex_to_bytes(const void *hex, kal_int32 *length, void *bytes)
2661{
2662 kal_int8 *p_hex=(kal_int8*)hex, *p_bytes=(kal_int8*)bytes;
2663 kal_int32 len_hex=mcf_str_strlen(p_hex), i=0, j=0;
2664 kal_int8 temp[2];
2665
2666 //EXT_ASSERT(len_hex%2==0, len_hex, bytes, 0);
2667 if( len_hex%2==1 || len_hex<0 ){
2668 return NULL;
2669 }
2670
2671 kal_mem_set(p_bytes, 0, len_hex / 2);
2672 *length = 0;
2673
2674 for( i=0; i<(len_hex/2); i++ ) {
2675 temp[0] = p_hex[i * 2];
2676 temp[1] = p_hex[i * 2 + 1];
2677
2678 for (j=0; j<2; j++) {
2679 if (temp[j] >= 'A' && temp[j] <= 'F') {
2680 temp[j] = temp[j] - 'A' + 10;
2681 } else if (temp[j] >= 'a' && temp[j] <= 'f') {
2682 temp[j] = temp[j] - 'a' + 10;
2683 } else if (temp[j] >= '0' && temp[j] <= '9') {
2684 temp[j] = temp[j] - '0';
2685 } else {
2686 return NULL;
2687 }
2688 }
2689 p_bytes[i] = (temp[0]<<4) | temp[1];
2690 }
2691 *length = len_hex / 2;
2692
2693 return p_bytes;
2694}
2695
2696void mcf_replace_char(kal_char* src, kal_char old_ch, kal_char new_ch)
2697{
2698 kal_uint32 k = 0;
2699 while(src[k] != 0)
2700 {
2701 if(src[k] == old_ch){
2702 src[k] = new_ch;
2703 }
2704 k++;
2705 }
2706
2707}
2708
2709void mcf_snprintf(kal_char * str, size_t num, const char * fmt, ...)
2710{
2711 kal_int32 ret_snprintf = 0;
2712 va_list arglist;
2713
2714 va_start(arglist, fmt);
2715 ret_snprintf = vsnprintf(str, num, fmt, arglist);
2716 va_end(arglist);
2717 if (ret_snprintf < 0 || ret_snprintf > num){
2718 strncpy(str, "unknown error", num - 1);
2719 MD_TRC_MCF_TR_MCF_SNPRINTF_FAIL(num, ret_snprintf);
2720 }
2721}
2722
2723#ifdef __MCF_FIND_TAG_SUPPORT__
2724extern MCF_DB_LID_MAPPING mcf_db_lid_mapping_tbl[];
2725extern MCF_DB_STRUCT_IDX mcf_db_struct_idx_tbl[];
2726kal_int32 mcf_parser_binary_search_struct_list(char *find_string, MCF_DB_STRUCT_VARIABLE const *struct_ptr, kal_uint32 struct_size)
2727{
2728 kal_int32 first = 0, // First array element
2729 last = struct_size - 1, // Last array element
2730 middle, // Mid point of search
2731 position = -1; // Position of search value
2732 kal_bool found = KAL_FALSE; // Flag
2733
2734 while (!found && first <= last)
2735 {
2736 middle = (first + last) / 2; // Calculate mid point
2737 if(middle < 0)
2738 return -1;
2739 if (mcf_str_strcmp(struct_ptr[middle].variable_name, find_string) == 0) // If value is found at mid
2740 {
2741 found = KAL_TRUE;
2742 position = middle;
2743 }
2744 else if (mcf_str_strcmp(struct_ptr[middle].variable_name, find_string) > 0) // If value is in lower half
2745 last = middle - 1;
2746 else
2747 first = middle + 1; // If value is in upper half
2748 }
2749 return position;
2750}
2751#endif
2752kal_bool mcf_find_tag_offset(
2753 kal_uint32 lid_num,
2754 char *tag_name,
2755 kal_uint16 *byte_offset,
2756 kal_uint16 *bit_offset,
2757 kal_uint32 *size,
2758 MCF_DB_STRUCT_VARIABLE const **var_ptr,
2759 mcf_tag_info_struct *tag_ptr)
2760{
2761#ifdef __MCF_FIND_TAG_SUPPORT__
2762 kal_uint16 i = 0;
2763 kal_uint16 array_size_cnt = 1;
2764 kal_int32 lid_idx = -1, struct_idx = -1;
2765 char *saveptr = NULL, *saveptr2 = NULL, *varstr = NULL, *substr = NULL;
2766 char var_name[MAX_VAR_LEN] = {0};
2767 kal_bool next_is_bit = KAL_FALSE;
2768 kal_uint32 start_time = GET_CURRENT_TIME();
2769
2770 if(tag_name == NULL || byte_offset == NULL || bit_offset == NULL || size == NULL)
2771 {
2772 MD_TRC_MCF_TR_FIND_TAG_ERROR_INPUT_NULL();
2773 return KAL_FALSE;
2774 }
2775
2776 *byte_offset = 0;
2777 *bit_offset = 0;
2778 *size= 0;
2779 dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, tag_name);
2780
2781 for(i = 0 ; i < MCF_LID_MAPPING_TBL_SIZE ; i++)
2782 {
2783 if(mcf_db_lid_mapping_tbl[i].lid_num == lid_num)
2784 {
2785 lid_idx = i;
2786 struct_idx = mcf_db_lid_mapping_tbl[i].struct_idx;
2787 break;
2788 }
2789 }
2790
2791 // can not find this lid_num in mcf_db_lid_mapping_tbl
2792 if(lid_idx == -1 || struct_idx > MCF_STRUCT_LIST_TBL_SIZE)
2793 {
2794 MD_TRC_MCF_TR_FIND_TAG_ERROR_CAN_NOT_FIND_LID_NUM(lid_num, struct_idx);
2795 return KAL_FALSE;
2796 }
2797
2798 // split "." for each variable
2799 substr = kal_strtok_r(tag_name, ".", &saveptr);
2800 while (substr){
2801 kal_int32 pos = -1;
2802 MCF_DB_STRUCT_VARIABLE const *var_struct_ptr = NULL;
2803
2804 // split "[" for get array num
2805 varstr = kal_strtok_r(substr, "[", &saveptr2);
2806 if(next_is_bit == KAL_TRUE){
2807 kal_uint32 len = strlen(var_name);
2808 var_name[len] = '.';
2809 strcpy(var_name + len + 1, varstr);
2810 }
2811 else
2812 {
2813 strcpy(var_name, varstr);
2814 }
2815
2816 var_struct_ptr = mcf_db_struct_idx_tbl[struct_idx].struct_ptr;
2817 pos = mcf_parser_binary_search_struct_list(var_name, var_struct_ptr, mcf_db_struct_idx_tbl[struct_idx].struct_size);
2818 if(pos == -1)
2819 {
2820 MCF_BOOT_TRACE(MCF_BOOT_TR_FIND_TAG_ERROR_CAN_NOT_FIND_TAG);
2821 MD_TRC_MCF_TR_FIND_TAG_ERROR_CAN_NOT_FIND_TAG();
2822 dhl_print_string(TRACE_ERROR, DHL_USER_FLAG_NONE, MOD_MCF, var_name);
2823 return KAL_FALSE;
2824 }
2825
2826 // get array size
2827 if(next_is_bit == KAL_TRUE)
2828 {
2829 *bit_offset += var_struct_ptr[pos].bit_offset;
2830 *size = var_struct_ptr[pos].total_size;
2831 }
2832 else
2833 {
2834 kal_uint32 array_size;
2835 kal_uint8 i = 0;
2836 tag_ptr->arr_cnt = 0;
2837 *byte_offset += var_struct_ptr[pos].byte_offset;
2838 *size = var_struct_ptr[pos].variable_size;
2839
2840 varstr = kal_strtok_r(NULL, "[", &saveptr2);
2841 if(varstr != NULL){
2842 do{
2843 kal_uint8 j = 0;
2844 kal_uint32 n = 1;
2845 array_size = mcf_atoi(varstr);
2846 j = i+1;
2847 while(var_struct_ptr[pos].array_size[j] != 0)
2848 {
2849 n *= (var_struct_ptr[pos].array_size[j]);
2850 j++;
2851 array_size_cnt++;
2852 }
2853 i++;
2854 *byte_offset += (array_size * n * var_struct_ptr[pos].variable_size);
2855 tag_ptr->array_size[tag_ptr->arr_cnt] = array_size;
2856 tag_ptr->arr_cnt++;
2857 }while((varstr = kal_strtok_r(NULL, "[", &saveptr2)) != NULL);
2858
2859 if (i > array_size_cnt){
2860 MD_TRC_MCF_TR_FIND_TAG_ERROR_OVER_SIZE(i, array_size_cnt);
2861 dhl_print_string(TRACE_ERROR, DHL_USER_FLAG_NONE, MOD_MCF, var_name);
2862 return KAL_FALSE;
2863 }
2864 }
2865 else{
2866 *size = var_struct_ptr[pos].total_size;
2867 }
2868 }
2869
2870 if(var_struct_ptr[pos].is_bit)
2871 {
2872 next_is_bit = KAL_TRUE;
2873 tag_ptr->is_bit = KAL_TRUE;
2874 tag_ptr->upper_vsize = var_struct_ptr[pos].variable_size;
2875 }
2876
2877 if(var_struct_ptr[pos].struct_idx != -1)
2878 {
2879 struct_idx = var_struct_ptr[pos].struct_idx;
2880 }
2881
2882 substr = kal_strtok_r(NULL, ".", &saveptr);
2883 if (substr != 0){
2884 tag_ptr->arr_cnt = 0;
2885 kal_mem_set(tag_ptr->array_size, 0, 5);
2886 }
2887 *var_ptr = &var_struct_ptr[pos];
2888 };
2889
2890 MD_TRC_MCF_TR_FIND_TAG_RETURN_VALUE(lid_num, *byte_offset, *bit_offset, *size, CALCULATE_LETENCY_DURATION(start_time, GET_CURRENT_TIME()));
2891
2892 return KAL_TRUE;
2893#else
2894 return KAL_FALSE;
2895#endif
2896}
2897
2898#ifdef __MCF_FIND_GID_SUPPORT__
2899extern MCF_DB_GID_LIST_STRUCT MCF_DB_GID_LIST[];
2900extern MCF_DB_GID_FORMULA_STRUCT MCF_DB_FORMULA_LIST[];
2901kal_int32 mcf_gid_binary_search_gid_list(kal_uint32 gid)
2902{
2903 kal_int32 first = 0, // First array element
2904 last = MCF_MAX_GID_LIST_SIZE - 1, // Last array element
2905 middle, // Mid point of search
2906 position = -1; // Position of search value
2907 kal_bool found = KAL_FALSE; // Flag
2908
2909 while (!found && first <= last)
2910 {
2911 middle = (first + last) / 2; // Calculate mid point
2912 if(middle < 0)
2913 return -1;
2914 if (gid == MCF_DB_GID_LIST[middle].gid) // If value is found at mid
2915 {
2916 found = KAL_TRUE;
2917 position = middle;
2918 }
2919 else if (gid < MCF_DB_GID_LIST[middle].gid) // If value is in lower half
2920 last = middle - 1;
2921 else
2922 first = middle + 1; // If value is in upper half
2923 }
2924 return position;
2925}
2926kal_int32 mcf_gid_binary_search_gid_formula_list(kal_uint32 gid)
2927{
2928 kal_int32 first = 0, // First array element
2929 last = MCF_MAX_GID_FORMULA_LIST_SIZE - 1, // Last array element
2930 middle, // Mid point of search
2931 position = -1; // Position of search value
2932 kal_bool found = KAL_FALSE; // Flag
2933
2934 while (!found && first <= last)
2935 {
2936 middle = (first + last) / 2; // Calculate mid point
2937 if(middle < 0)
2938 return -1;
2939 if (gid == MCF_DB_FORMULA_LIST[middle].gid) // If value is found at mid
2940 {
2941 found = KAL_TRUE;
2942 position = middle;
2943 }
2944 else if (gid < MCF_DB_FORMULA_LIST[middle].gid) // If value is in lower half
2945 last = middle - 1;
2946 else
2947 first = middle + 1; // If value is in upper half
2948 }
2949 return position;
2950}
2951#endif
2952kal_bool mcf_find_gid_offset(
2953 kal_uint32 gid,
2954 char *array_idx_string,
2955 kal_uint16 *lid_num,
2956 kal_uint16 *byte_offset,
2957 kal_uint16 *bit_offset,
2958 kal_uint32 *size,
2959 kal_bool *is_bit
2960)
2961{
2962#ifdef __MCF_FIND_GID_SUPPORT__
2963 kal_int32 gid_list_pos = 0, gid_formula_list_pos = 0;
2964 kal_uint32 start_time = GET_CURRENT_TIME();
2965
2966 if(byte_offset == NULL || bit_offset == NULL || size == NULL || is_bit == NULL || array_idx_string == NULL)
2967 {
2968 MD_TRC_MCF_TR_FIND_GID_ERROR_INPUT_NULL();
2969 return KAL_FALSE;
2970 }
2971
2972 MD_TRC_MCF_TR_FIND_GID_START(gid, array_idx_string);
2973
2974 gid_list_pos = mcf_gid_binary_search_gid_list(gid);
2975 if(gid_list_pos == -1 || gid_list_pos < 0)
2976 {
2977 MCF_BOOT_TRACE(MCF_BOOT_TR_FIND_GID_ERROR_CAN_NOT_FIND_GID, gid);
2978 MD_TRC_MCF_TR_FIND_GID_ERROR_CAN_NOT_FIND_GID(gid);
2979 return KAL_FALSE;
2980 }
2981
2982 *lid_num = MCF_DB_GID_LIST[gid_list_pos].lid_num;
2983 *size = MCF_DB_GID_LIST[gid_list_pos].variable_size;
2984 *is_bit = MCF_DB_GID_LIST[gid_list_pos].is_bit;
2985 *bit_offset = MCF_DB_GID_LIST[gid_list_pos].bit_offset;
2986 if(MCF_DB_GID_LIST[gid_list_pos].array_formula == KAL_FALSE)
2987 {
2988 *byte_offset = MCF_DB_GID_LIST[gid_list_pos].byte_offset;
2989 }
2990 else
2991 {
2992 kal_int32 array_size[10] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
2993 kal_uint32 i = 0, j = 0;
2994 kal_uint32 current_array_i = 0;
2995 char *saveptr = NULL, *saveptr2 = NULL, *varstr = NULL, *substr = NULL;
2996 char gid_formula_string[MCF_MAX_FORMULA_LEN] = {0};
2997 char temp_array_idx[64] = {0};
2998
2999 *byte_offset = 0;
3000 strncpy(temp_array_idx, array_idx_string, 63);
3001 temp_array_idx[63] = '\0';
3002 // parsing array_idx_string
3003 varstr = kal_strtok_r(temp_array_idx, "$", &saveptr);
3004 if(varstr != NULL){
3005 do{
3006 array_size[i++] = mcf_atoi(varstr);
3007 if(i >= 10)
3008 {
3009 MCF_BOOT_TRACE(MCF_BOOT_TR_FIND_GID_ERROR_FORMULA_OUT_OF_BOUND , gid);
3010 MD_TRC_MCF_TR_FIND_GID_ERROR_FORMULA_OUT_OF_BOUND(gid);
3011 dhl_print_string(TRACE_ERROR, DHL_USER_FLAG_NONE, MOD_MCF, temp_array_idx);
3012 return KAL_FALSE;
3013 }
3014 }while((varstr = kal_strtok_r(NULL, "$", &saveptr)) != NULL);
3015
3016 }
3017
3018 gid_formula_list_pos = mcf_gid_binary_search_gid_formula_list(gid);
3019 if(gid_formula_list_pos == -1 || gid_formula_list_pos < 0)
3020 {
3021 MCF_BOOT_TRACE(MCF_BOOT_TR_FIND_GID_ERROR_CAN_NOT_FIND_FORMULA, gid);
3022 MD_TRC_MCF_TR_FIND_GID_ERROR_CAN_NOT_FIND_FORMULA(gid);
3023 return KAL_FALSE;
3024 }
3025
3026 //[5](0,164)+[8](4,20)+[5](0,4)+0
3027 //[10](0,12)+2+2
3028 //[2,8,2](4,2)
3029 strncpy(gid_formula_string, MCF_DB_FORMULA_LIST[gid_formula_list_pos].byte_offset_formula, MCF_MAX_FORMULA_LEN - 1);
3030 substr = kal_strtok_r(gid_formula_string, "+", &saveptr);
3031 if(substr != NULL){
3032 do{
3033 kal_int32 max_array_idx[5] = {-1,-1,-1,-1,-1};
3034 kal_uint32 local_base = 0, local_size = 0, base = 0;
3035 kal_uint32 max_array_i = 0;
3036 kal_bool max_array_start = KAL_FALSE, local_start = KAL_FALSE, base_start = KAL_TRUE;
3037 char temp[20] = {0};
3038
3039 j = 0;
3040 while(substr[j] != '\0')
3041 {
3042 if(substr[j] == '['){
3043 max_array_start = KAL_TRUE; local_start = KAL_FALSE; base_start = KAL_FALSE;
3044 kal_mem_set(temp, 0, 20);
3045 i = 0;
3046 }
3047 else if(substr[j] == ']'){
3048 max_array_start = KAL_FALSE; local_start = KAL_FALSE; base_start = KAL_FALSE;
3049 varstr = kal_strtok_r(temp, ",", &saveptr2);
3050 if(varstr != NULL){
3051 do{
3052 max_array_idx[max_array_i++] = mcf_atoi(varstr);
3053 }while((varstr = kal_strtok_r(NULL, ",", &saveptr2)) != NULL);
3054 }
3055 }
3056 else if(substr[j] == '('){
3057 max_array_start = KAL_FALSE; local_start = KAL_TRUE; base_start = KAL_FALSE;
3058 kal_mem_set(temp, 0, 20);
3059 i = 0;
3060 }
3061 else if(substr[j] == ')'){
3062 max_array_start = KAL_FALSE; local_start = KAL_FALSE; base_start = KAL_FALSE;
3063 varstr = kal_strtok_r(temp, ",", &saveptr2);
3064 if (varstr != NULL){
3065 local_base = mcf_atoi(varstr);
3066 }
3067 varstr = kal_strtok_r(NULL, ",", &saveptr2);
3068 if (varstr != NULL){
3069 local_size = mcf_atoi(varstr);
3070 }
3071 }
3072 else // digit
3073 {
3074 // get max array idx
3075 if(max_array_start == KAL_TRUE)
3076 {
3077 temp[i++] = substr[j];
3078 }
3079 else if(local_start == KAL_TRUE)
3080 {
3081 temp[i++] = substr[j];
3082 }
3083 else if(base_start == KAL_TRUE)
3084 {
3085 base = mcf_atoi(substr);
3086 }
3087 }
3088
3089 j++;
3090 }
3091 {
3092 kal_uint32 temp_offset = 0;
3093 for(i = 0; i< max_array_i; i++)
3094 {
3095 kal_uint32 array_idx = array_size[current_array_i++];
3096 kal_uint32 array_offset = 0;
3097 if(array_idx == -1) break;
3098 array_offset = array_idx * local_size;
3099
3100 if(array_idx >= max_array_idx[i])
3101 {
3102 return KAL_FALSE; // array size error
3103 }
3104 for(j = i + 1 ; j < 5 ; j++)
3105 {
3106 if(max_array_idx[j] == -1) break;
3107 array_offset *= max_array_idx[j];
3108 }
3109 temp_offset += array_offset;
3110
3111 }
3112 *byte_offset += temp_offset + local_base;
3113
3114 }
3115 *byte_offset += base;
3116
3117 }while((substr = kal_strtok_r(NULL, "+", &saveptr)) != NULL);
3118 }
3119
3120
3121 }
3122
3123 MD_TRC_MCF_TR_FIND_GID_RETURN_VALUE(*lid_num, *byte_offset, *bit_offset, *size, *is_bit, CALCULATE_LETENCY_DURATION(start_time, GET_CURRENT_TIME()));
3124
3125 return KAL_TRUE;
3126#else
3127 return KAL_FALSE;
3128#endif
3129}
3130
3131kal_uint16 mcf_find_gid_return_lid_num(kal_uint32 gid)
3132{
3133#ifdef __MCF_FIND_GID_SUPPORT__
3134 kal_int32 gid_list_pos = 0;
3135 gid_list_pos = mcf_gid_binary_search_gid_list(gid);
3136 if(gid_list_pos == -1 || gid_list_pos < 0)
3137 {
3138 MCF_BOOT_TRACE(MCF_BOOT_TR_FIND_GID_RETURN_LID_NUM_ERROR_CAN_NOT_FIND_GID, gid);
3139 MD_TRC_MCF_TR_FIND_GID_RETURN_LID_NUM_ERROR_CAN_NOT_FIND_GID(gid);
3140 return -1; // not found
3141 }
3142 return MCF_DB_GID_LIST[gid_list_pos].lid_num;
3143#else
3144 return -1;
3145#endif
3146}
3147
3148kal_uint32 mcf_calc_check_sum(kal_uint32 *ptr, kal_uint32 len)
3149{
3150 kal_uint32 check_sum = 0, i = 0;
3151 for(i = 0; i< (len/sizeof(kal_uint32)) ; i++, ptr++)
3152 check_sum += *ptr;
3153 check_sum = ~check_sum + 1;
3154 return check_sum;
3155}
3156kal_uint32 mcf_check_check_sum(kal_uint32 *ptr, kal_uint32 len)
3157{
3158 kal_uint32 check_sum = 0, i = 0;
3159 for(i = 0; i< (len/sizeof(kal_uint32)) ; i++, ptr++)
3160 check_sum += *ptr;
3161
3162 if(check_sum != 0)
3163 MD_TRC_MCF_TR_CHECKSUM_ERROR(check_sum);
3164
3165 return check_sum;
3166}
3167
3168// password will be auto padding to 16B
3169// content should be padding to 16B alignment
3170// conrent length should be mod by 16
3171kal_bool mcf_encrypt_128bit(char *password, char *content, kal_uint32 content_length)
3172{
3173 kal_uint8 iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
3174 kal_uint8 copy_len = 0;
3175 kal_uint32 output_len;
3176 t_cust_chl_sym_key key;
3177 AES_PARAM aes_param;
3178 kal_uint32 ret = CUST_CHL_ERROR_NONE;
3179 kal_uint32 start_time = ust_get_current_time();
3180
3181 if(content == NULL) return KAL_FALSE;
3182 if(content_length % 16 != 0) return KAL_FALSE;
3183
3184 copy_len = strlen(password);
3185 if(copy_len > 16) copy_len = 16;
3186
3187 key.m_key_len = 16;
3188 kal_mem_set(key.m_key, 0, sizeof(key.m_key));
3189 kal_mem_cpy(&key.m_key, password, copy_len);
3190 aes_param.IVLength = 16;
3191 aes_param.IV = iv;
3192 ret = CustCHL_AES_Encrypt_data(CUST_CHL_ALG_AES128, CUST_CHL_MODE_CBC, content_length, (kal_uint8 *)content, &output_len, (kal_uint8 *)content, &key, &aes_param);
3193
3194 MD_TRC_MCF_TR_ENCRYPT(ust_us_duration(start_time, ust_get_current_time()));
3195 if (ret != CUST_CHL_ERROR_NONE)
3196 return KAL_FALSE;
3197 return KAL_TRUE;
3198}
3199
3200// password will be auto padding to 16B
3201// content should be padding to 16B alignment
3202// conrent length should be mod by 16
3203kal_bool mcf_decrypt_128bit(char *password, char *content, kal_uint32 content_length)
3204{
3205 kal_uint8 iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
3206 kal_uint8 copy_len = 0;
3207 kal_uint32 output_len;
3208 t_cust_chl_sym_key key;
3209 AES_PARAM aes_param;
3210 kal_uint32 ret = CUST_CHL_ERROR_NONE;
3211 kal_uint32 start_time = ust_get_current_time();
3212
3213 if(content == NULL) return KAL_FALSE;
3214 if(content_length % 16 != 0) return KAL_FALSE;
3215
3216 copy_len = strlen(password);
3217 if(copy_len > 16) copy_len = 16;
3218
3219 key.m_key_len = 16;
3220 kal_mem_set(key.m_key, 0, sizeof(key.m_key));
3221 kal_mem_cpy(&key.m_key, password, copy_len);
3222 aes_param.IVLength = 16;
3223 aes_param.IV = iv;
3224 ret = CustCHL_AES_Decrypt_data(CUST_CHL_ALG_AES128, CUST_CHL_MODE_CBC, content_length, (kal_uint8 *)content, &output_len, (kal_uint8 *)content, &key, &aes_param);
3225
3226 MD_TRC_MCF_TR_DECRYPT(ust_us_duration(start_time, ust_get_current_time()));
3227 if (ret != CUST_CHL_ERROR_NONE)
3228 return KAL_FALSE;
3229
3230 return KAL_TRUE;
3231}
3232#ifdef __MCF_COMBINE_FILE_SUPPORT__
3233void mcf_merge_insert_node(mcf_merge_link_list_struct *pre_node, mcf_merge_link_list_struct *next_node, mcf_merge_link_list_struct *insert_node, void *insert_data)
3234{
3235 if(pre_node != NULL) pre_node->next_node = insert_node;
3236 if(next_node != NULL) next_node->pre_node = insert_node;
3237 insert_node->pre_node = pre_node;
3238 insert_node->next_node = next_node;
3239 insert_node->data = insert_data;
3240 MD_TRC_MCF_TR_MERGE_LINK_LIST_INSERT_NODE_INFO((pre_node != NULL)?(kal_uint32)pre_node->next_node : 0,
3241 (next_node != NULL)?(kal_uint32)next_node->pre_node : 0,
3242 (kal_uint32)insert_node->pre_node, (kal_uint32)insert_node->next_node);
3243}
3244
3245// comparison sequence : LID => RID => GID => array idx
3246kal_int8 mcf_merge_compare_ota_data(mcf_tool_gid_ota_file_item_t *first_data, mcf_tool_gid_ota_file_item_t *second_data)
3247{
3248 kal_uint16 first_lid_num = mcf_find_gid_return_lid_num(first_data->global_id);
3249 kal_uint16 second_lid_num = mcf_find_gid_return_lid_num(second_data->global_id);
3250 kal_int32 array_cmp_result = 0;
3251
3252 MD_TRC_MCF_TR_MERGE_CMP_OTA_DATA_INFO(first_lid_num, first_data->record_idx, first_data->global_id, second_lid_num, second_data->record_idx, second_data->global_id);
3253
3254 if(first_lid_num < second_lid_num) return -1;
3255 else if (first_lid_num > second_lid_num) return 1;
3256
3257 if(first_data->record_idx < second_data->record_idx) return -1;
3258 else if (first_data->record_idx > second_data->record_idx) return 1;
3259
3260 if(first_data->global_id < second_data->global_id) return -1;
3261 else if (first_data->global_id > second_data->global_id) return 1;
3262
3263 if (first_data->array_index_len > 0)
3264 {
3265 array_cmp_result= strncmp(&(first_data->buff_start), &(second_data->buff_start), first_data->array_index_len);
3266 MD_TRC_MCF_TR_MERGE_CMP_OTA_DATA_ARRAY_INFO(array_cmp_result);
3267 if (array_cmp_result < 0) return -1;
3268 if (array_cmp_result > 0) return 1;
3269 }
3270
3271 return 0;
3272}
3273
3274kal_int8 mcf_merge_compare_ota_by_op_tag(char *tag1, char *tag2)
3275{
3276 kal_uint16 tag1_sbpid= 0, tag1_mcc=0, tag1_mnc=0, tag2_sbpid=0, tag2_mcc=0, tag2_mnc=0; // use 0 as "NA"
3277 kal_char sbp_id_tag[MCF_MAX_TAG_NUM] = {0};
3278 const char *delim = "_";
3279 char * pch;
3280 kal_char *saveptr = NULL;
3281 // parsing tag1
3282 strncpy(sbp_id_tag, tag1, MCF_MAX_TAG_NUM-1);
3283 pch = kal_strtok_r(sbp_id_tag, delim, &saveptr);
3284 if (pch != NULL && strcmp(pch, "NA") != 0) tag1_sbpid = mcf_atoi(pch);
3285 pch = kal_strtok_r(NULL, delim, &saveptr);
3286 if (pch != NULL && strcmp(pch, "NA") != 0) tag1_mcc = mcf_atoi(pch);
3287 pch = kal_strtok_r(NULL, delim, &saveptr);
3288 if (pch != NULL && strcmp(pch, "NA") != 0) tag1_mnc = mcf_atoi(pch);
3289 // parsing tag2
3290 strncpy(sbp_id_tag, tag2, MCF_MAX_TAG_NUM-1);
3291 pch = kal_strtok_r(sbp_id_tag, delim, &saveptr);
3292 if (pch != NULL && strcmp(pch, "NA") != 0) tag2_sbpid = mcf_atoi(pch);
3293 pch = kal_strtok_r(NULL, delim, &saveptr);
3294 if (pch != NULL && strcmp(pch, "NA") != 0) tag2_mcc = mcf_atoi(pch);
3295 pch = kal_strtok_r(NULL, delim, &saveptr);
3296 if (pch != NULL && strcmp(pch, "NA") != 0) tag2_mnc = mcf_atoi(pch);
3297
3298 // comparion
3299 // SBP
3300 if ((tag1_sbpid == tag2_sbpid) && (tag1_mcc == tag2_mcc) && (tag1_mnc == tag2_mnc))
3301 return 0;
3302 else if (tag1_sbpid > tag2_sbpid)
3303 return 1;
3304 else if (tag1_sbpid < tag2_sbpid)
3305 return -1;
3306 else
3307 {
3308 // SBP is equal, then compare MCC
3309 if (tag1_mcc > tag2_mcc) return 1;
3310 else if (tag1_mcc < tag2_mcc) return -1;
3311 else
3312 {
3313 // SBP and MCC are equal, then compare MNC
3314 if (tag1_mnc > tag2_mnc) return 1;
3315 else if (tag1_mnc < tag2_mnc) return -1;
3316 }
3317 }
3318 return 0;
3319}
3320
3321// comparison sequence : LID => TAG type=> TAG => GID => array idx
3322kal_int8 mcf_merge_compare_ota_by_op_data(mcf_tool_gid_tlvota_file_item_t *first_data, mcf_tool_gid_tlvota_file_item_t *second_data)
3323{
3324 kal_uint16 first_lid_num = mcf_find_gid_return_lid_num(first_data->global_id);
3325 kal_uint16 second_lid_num = mcf_find_gid_return_lid_num(second_data->global_id);
3326 kal_int32 array_cmp_result = 0;
3327
3328 MD_TRC_MCF_TR_MERGE_CMP_OTA_DATA_INFO(first_lid_num, first_data->tag_type, first_data->global_id, second_lid_num, second_data->tag_type, second_data->global_id);
3329
3330 if(first_lid_num < second_lid_num) return -1;
3331 else if (first_lid_num > second_lid_num) return 1;
3332
3333 if(first_data->tag_type < second_data->tag_type) return -1;
3334 else if (first_data->tag_type > second_data->tag_type) return 1;
3335
3336 {
3337 kal_char sbp_tag1[MCF_FILE_MAX_TAG_LEN] = {0};
3338 kal_char sbp_tag2[MCF_FILE_MAX_TAG_LEN] = {0};
3339 kal_int8 result= 0;
3340
3341 strncpy(sbp_tag1, &(first_data->buff_start) , first_data->tag_len);
3342 strncpy(sbp_tag2, &(second_data->buff_start) , second_data->tag_len);
3343
3344 result= mcf_merge_compare_ota_by_op_tag(sbp_tag1, sbp_tag2);
3345 if(result < 0) return -1;
3346 if(result > 0) return 1;
3347 }
3348
3349 if(first_data->global_id < second_data->global_id) return -1;
3350 else if (first_data->global_id > second_data->global_id) return 1;
3351
3352 if (first_data->array_index_len > 0)
3353 {
3354 array_cmp_result = strncmp(&(first_data->buff_start) + first_data->tag_len, &(second_data->buff_start) + second_data->tag_len, first_data->array_index_len);
3355 MD_TRC_MCF_TR_MERGE_CMP_OTA_DATA_ARRAY_INFO(array_cmp_result);
3356 if (array_cmp_result < 0) return -1;
3357 if (array_cmp_result > 0) return 1;
3358 }
3359
3360 return 0;
3361}
3362
3363// sort by ascending
3364mcf_merge_link_list_struct * mcf_merge_link_list_insert(mcf_merge_link_list_struct *head, mcf_merge_link_list_struct *tail, mcf_merge_link_list_struct *current, void *insert_data, mcf_ota_type_enum type)
3365{
3366 mcf_merge_link_list_struct *current_node = head->next_node;
3367 mcf_merge_link_list_struct *new_node = NULL;
3368 kal_int8 result = 0;
3369 if (type == MCF_TYPE_OTA) MD_TRC_MCF_TR_MERGE_LINK_LIST_INSERT_DATA_START(((mcf_tool_gid_ota_file_item_t *)insert_data)->global_id);
3370 else if (type == MCF_TYPE_OTA_BY_OP) MD_TRC_MCF_TR_MERGE_LINK_LIST_INSERT_DATA_START(((mcf_tool_gid_tlvota_file_item_t *)insert_data)->global_id);
3371
3372 if (current != NULL)
3373 {
3374 // quick determine
3375 if (type == MCF_TYPE_OTA)
3376 {
3377 result = mcf_merge_compare_ota_data((mcf_tool_gid_ota_file_item_t *)insert_data, (mcf_tool_gid_ota_file_item_t *)current->data);
3378 }
3379 else if (type == MCF_TYPE_OTA_BY_OP)
3380 {
3381 result = mcf_merge_compare_ota_by_op_data((mcf_tool_gid_tlvota_file_item_t *)insert_data, (mcf_tool_gid_tlvota_file_item_t *)current->data);
3382 }
3383 else
3384 {
3385 DEBUG_ASSERT(0);
3386 return NULL;
3387 }
3388 MD_TRC_MCF_TR_MERGE_LINK_LIST_INSERT_CMP_RESULT(result);
3389 // if insert data >= current, then start from current.
3390 // if insert data < current, back to head to find again.
3391 if (result == 1 || result == 0) {
3392 current_node = current;
3393 MD_TRC_MCF_TR_MERGE_LINK_LIST_USE_CURRENT_AS_START();
3394 }
3395 else {
3396 current_node = head->next_node;
3397 MD_TRC_MCF_TR_MERGE_LINK_LIST_USE_HEAD_AS_START();
3398 }
3399 }
3400
3401 while (current_node != tail)
3402 {
3403 // ========= COMPARE NODE =========
3404 result = 0;
3405 if (type == MCF_TYPE_OTA)
3406 {
3407 result = mcf_merge_compare_ota_data((mcf_tool_gid_ota_file_item_t *)insert_data, (mcf_tool_gid_ota_file_item_t *)current_node->data);
3408 }
3409 else if (type == MCF_TYPE_OTA_BY_OP)
3410 {
3411 result = mcf_merge_compare_ota_by_op_data((mcf_tool_gid_tlvota_file_item_t *)insert_data, (mcf_tool_gid_tlvota_file_item_t *)current_node->data);
3412 }
3413 else
3414 {
3415 DEBUG_ASSERT(0);
3416 return NULL;
3417 }
3418 MD_TRC_MCF_TR_MERGE_LINK_LIST_INSERT_CMP_RESULT(result);
3419 // ========= INSERT NODE =========
3420 // insert data should be inserted BEFORE current node
3421 if (result == -1)
3422 {
3423 new_node = mcf_malloc(sizeof(mcf_merge_link_list_struct));
3424 if(new_node == NULL) return NULL;
3425 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_ALLOCATE((kal_uint32)new_node);
3426 kal_mem_set(new_node, 0, sizeof(mcf_merge_link_list_struct));
3427 mcf_merge_insert_node(current_node->pre_node, current_node, new_node, insert_data);
3428 return current_node->pre_node;
3429 }
3430 // insert data should be REPLACED current node
3431 else if (result == 0)
3432 {
3433 current_node->data = insert_data;
3434 return current_node;
3435 }
3436 // insert data should be inserted AFTER current node
3437 else if (result == 1)
3438 {
3439 // due to the link list is acending, skip
3440 }
3441 else
3442 DEBUG_ASSERT(0);
3443
3444 current_node = current_node->next_node;
3445 }
3446
3447 // insert the last
3448 new_node = mcf_malloc(sizeof(mcf_merge_link_list_struct));
3449 if(new_node == NULL) return NULL;
3450 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_ALLOCATE((kal_uint32)new_node);
3451 kal_mem_set(new_node, 0, sizeof(mcf_merge_link_list_struct));
3452 mcf_merge_insert_node(current_node->pre_node, current_node, new_node, insert_data);
3453
3454 return current_node->pre_node;
3455}
3456
3457void mcf_merge_link_list_free(mcf_merge_link_list_struct *head)
3458{
3459 mcf_merge_link_list_struct *current = head;
3460 while (current != NULL)
3461 {
3462 mcf_merge_link_list_struct *next = current->next_node;
3463 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_FREE((kal_uint32)current);
3464 mcf_free(current);
3465 current = next;
3466 }
3467}
3468
3469kal_bool mcf_merge_read_buffer_to_linklist(void *buffer, mcf_merge_link_list_struct *head, mcf_merge_link_list_struct *tail, mcf_ota_type_enum type)
3470{
3471 mcf_tool_file_info_t *file_header = (mcf_tool_file_info_t *)buffer;
3472 kal_uint32 item_cnt = 0;
3473 mcf_merge_link_list_struct *current = NULL;
3474
3475 if (type == MCF_TYPE_OTA) {
3476 mcf_tool_gid_ota_file_item_t *current_data = (mcf_tool_gid_ota_file_item_t *)((kal_uint8 *)file_header + file_header->total_len);
3477 MD_TRC_MCF_TR_MERGE_READ_BUFFER_TO_LINKLIST_TOTAL_ITEM(file_header->item_num);
3478 for (item_cnt = 0 ; item_cnt < file_header->item_num ; item_cnt ++)
3479 {
3480 current = mcf_merge_link_list_insert(head, tail, current, current_data, type);
3481 if(current == NULL) return KAL_FALSE;
3482 MD_TRC_MCF_TR_MERGE_READ_BUFFER_TO_LINKLIST_ITEM_INFO(item_cnt, current_data->global_id);
3483 current_data = (mcf_tool_gid_ota_file_item_t *)((kal_uint8 *)current_data + current_data->total_len);
3484 }
3485 }
3486 else if (type == MCF_TYPE_OTA_BY_OP)
3487 {
3488 mcf_tool_gid_tlvota_file_item_t *current_data = (mcf_tool_gid_tlvota_file_item_t *)((kal_uint8 *)file_header + file_header->total_len);
3489 MD_TRC_MCF_TR_MERGE_READ_BUFFER_TO_LINKLIST_TOTAL_ITEM(file_header->item_num);
3490 for (item_cnt = 0 ; item_cnt < file_header->item_num ; item_cnt ++)
3491 {
3492 current = mcf_merge_link_list_insert(head, tail, current, current_data, type);
3493 if(current == NULL) return KAL_FALSE;
3494 MD_TRC_MCF_TR_MERGE_READ_BUFFER_TO_LINKLIST_ITEM_INFO(item_cnt, current_data->global_id);
3495 current_data = (mcf_tool_gid_tlvota_file_item_t *)((kal_uint8 *)current_data + current_data->total_len);
3496 }
3497 }
3498 else
3499 {
3500 DEBUG_ASSERT(0);
3501 return KAL_FALSE;
3502 }
3503 return KAL_TRUE;
3504}
3505
3506void mcf_merge_make_ota_file_header(mcf_tool_file_info_t *output_header, mcf_tool_file_info_t *copy_header)
3507{
3508 kal_char sw_version[MCF_SW_VERNO_LEN] = {0};
3509 kal_char gen_time[MCF_FILE_MAX_GEN_TIME_LEN] = {0};
3510
3511 struct tm current_time;
3512
3513#if defined(__MTK_TARGET__) && defined(__SUPPORT_CLIB_TIME__)
3514 time_t currenttime;
3515 kal_mem_set(&current_time, 0, sizeof(struct tm));
3516 if (time(&currenttime) != -1)
3517 localtime_r(&currenttime, &current_time);
3518#else
3519 current_time.tm_year = 118;
3520 current_time.tm_mon = 0;
3521 current_time.tm_mday = 1;
3522 current_time.tm_hour = 0;
3523 current_time.tm_min = 0;
3524 current_time.tm_sec = 0;
3525#endif
3526 MD_TRC_MCF_TR_MERGE_MAKE_OTA_FILE_HEADER_START();
3527 kal_mem_set(output_header, 0, sizeof(mcf_tool_file_info_t));
3528
3529 kal_mem_set(sw_version, 0, sizeof(kal_char) * MCF_SW_VERNO_LEN);
3530 kal_mem_set(gen_time, 0, sizeof(kal_char) * MCF_FILE_MAX_GEN_TIME_LEN);
3531
3532 if(sprintf(gen_time,"%04d.%02d%02d.%02d%02d%02d", current_time.tm_year + 1900, current_time.tm_mon + 1, current_time.tm_mday, current_time.tm_hour, current_time.tm_min, current_time.tm_sec) <0)
3533 DEBUG_ASSERT(0);
3534 strncpy(sw_version, release_verno(), MCF_SW_VERNO_LEN-1);
3535
3536 output_header->sw_version_len = strlen(sw_version);
3537 output_header->gen_time_len = strlen(gen_time);
3538 output_header->file_version = copy_header->file_version;
3539 output_header->operation_mask = copy_header->operation_mask;
3540 if((output_header->operation_mask & MCF_FILE_OP_SHA256_RSA2048) || (output_header->operation_mask & MCF_FILE_OP_SHA384_RSA3072))
3541 {
3542 output_header->operation_mask &= ~(MCF_FILE_OP_SHA256_RSA2048);
3543 output_header->operation_mask &= ~(MCF_FILE_OP_SHA384_RSA3072);
3544 }
3545 strcpy(output_header->file_type, copy_header->file_type);
3546 // copy header
3547 {
3548 // use copy_len to prevent out of array
3549 kal_uint32 copy_len = 0;
3550 if (output_header->sw_version_len >= MCF_SW_VERNO_LEN -1) copy_len = MCF_SW_VERNO_LEN -1;
3551 else copy_len = output_header->sw_version_len;
3552 strncpy(&output_header->buff_start, sw_version, copy_len);
3553
3554 if (output_header->gen_time_len >= MCF_FILE_MAX_GEN_TIME_LEN -1) copy_len = MCF_FILE_MAX_GEN_TIME_LEN -1;
3555 else copy_len = output_header->gen_time_len;
3556 strncpy(&output_header->buff_start + output_header->sw_version_len, gen_time, copy_len);
3557 }
3558 output_header->total_len = (kal_uint32)&output_header->buff_start + output_header->sw_version_len + output_header->gen_time_len - (kal_uint32)output_header; // end addr - start addr
3559 if ((output_header->total_len % 4) != 0)
3560 output_header->total_len += 4 - (output_header->total_len % 4); // 4 bytes alignment
3561 MD_TRC_MCF_TR_MERGE_MAKE_OTA_FILE_HEADER_END();
3562}
3563
3564// if first buffer has same gid, it will be replaced by second_buffer
3565kal_bool mcf_merge_ota_buffer(void *first_buffer, void *second_buffer, void *output_buffer, kal_uint32 output_buffer_size)
3566{
3567 mcf_merge_link_list_struct *head, *tail;
3568 mcf_ota_type_enum type = 0;
3569 kal_bool ret = KAL_FALSE;
3570 kal_uint32 coreID = kal_get_current_core_id();
3571
3572 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_START();
3573 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_MCF_CORE(coreID);
3574 //If MCF is running on Core0, need to wake up Core1 to run other task
3575 if (coreID == 0){
3576 SleepDrv_LockSleep( SLEEP_CTL_MCF, CORE1);
3577 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_LOCK_CORE(CORE1, coreID);
3578 }
3579 if (first_buffer == NULL || second_buffer == NULL || output_buffer == NULL) {
3580 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_INPUT_PARAM_ERROR((kal_uint32)first_buffer, (kal_uint32)second_buffer, (kal_uint32)output_buffer);
3581 if (coreID == 0){
3582 SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1);
3583 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID);
3584 }
3585 return KAL_FALSE;
3586 }
3587
3588 // head init
3589 head = mcf_malloc(sizeof(mcf_merge_link_list_struct));
3590 tail = mcf_malloc(sizeof(mcf_merge_link_list_struct));
3591 if(head == NULL || tail == NULL){
3592 if (coreID == 0){
3593 SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1);
3594 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID);
3595 }
3596 return KAL_FALSE;
3597 }
3598 kal_mem_set(head, 0, sizeof(mcf_merge_link_list_struct));
3599 kal_mem_set(tail, 0, sizeof(mcf_merge_link_list_struct));
3600 head->next_node = tail;
3601 tail->pre_node = head;
3602 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_ALLOCATE_HEAD_TAIL((kal_uint32)head, (kal_uint32)tail);
3603 // ========== read first buffer ==========
3604 {
3605 mcf_tool_file_info_t *file_header = (mcf_tool_file_info_t *)first_buffer;
3606 if (strcmp(file_header->file_type, MCF_FILE_TYPE_OTA) == 0) type = MCF_TYPE_OTA;
3607 else if (strcmp(file_header->file_type, MCF_FILE_TYPE_TLVOTA) == 0) type = MCF_TYPE_OTA_BY_OP;
3608 else{
3609 DEBUG_ASSERT(0);
3610 if (coreID == 0){
3611 SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1);
3612 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID);
3613 }
3614 return KAL_FALSE;
3615 }
3616 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_FIRST_BUFFER_TYPE(type);
3617 ret = mcf_merge_read_buffer_to_linklist(first_buffer, head, tail, type);
3618 if(ret == KAL_FALSE){
3619 if (coreID == 0){
3620 SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1);
3621 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID);
3622 }
3623 return KAL_FALSE;
3624 }
3625 }
3626 // ========== read second buffer ==========
3627 {
3628 mcf_tool_file_info_t *file_header = (mcf_tool_file_info_t *)second_buffer;
3629 if (strcmp(file_header->file_type, MCF_FILE_TYPE_OTA) == 0) type = MCF_TYPE_OTA;
3630 else if (strcmp(file_header->file_type, MCF_FILE_TYPE_TLVOTA) == 0) type = MCF_TYPE_OTA_BY_OP;
3631 else{
3632 DEBUG_ASSERT(0);
3633 if (coreID == 0){
3634 SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1);
3635 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID);
3636 }
3637 return KAL_FALSE;
3638 }
3639 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_SECOND_BUFFER_TYPE(type);
3640 ret = mcf_merge_read_buffer_to_linklist(second_buffer, head, tail, type);
3641 if(ret == KAL_FALSE){
3642 if (coreID == 0){
3643 SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1);
3644 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID);
3645 }
3646 return KAL_FALSE;
3647 }
3648 }
3649 // ========== output buffer ==========
3650 {
3651 mcf_tool_file_info_t *copy_header = (mcf_tool_file_info_t *)second_buffer;
3652 mcf_tool_file_info_t *output_header = (mcf_tool_file_info_t *)output_buffer;
3653 kal_uint8 *current_pos = NULL;
3654 mcf_merge_link_list_struct *current_node = head->next_node;
3655
3656 mcf_merge_make_ota_file_header(output_header, copy_header); // copy first header to output header
3657 current_pos = (kal_uint8 *)output_header + output_header->total_len;
3658
3659 if (strcmp(output_header->file_type, MCF_FILE_TYPE_OTA) == 0) type = MCF_TYPE_OTA;
3660 else if (strcmp(output_header->file_type, MCF_FILE_TYPE_TLVOTA) == 0) type = MCF_TYPE_OTA_BY_OP;
3661 else{
3662 DEBUG_ASSERT(0);
3663 if (coreID == 0){
3664 SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1);
3665 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID);
3666 }
3667 return KAL_FALSE;
3668 }
3669
3670 while (current_node != tail)
3671 {
3672 if (type == MCF_TYPE_OTA)
3673 {
3674 mcf_tool_gid_ota_file_item_t *current_ota_data = current_node->data;
3675 kal_mem_cpy(current_pos, current_ota_data, current_ota_data->total_len);
3676 current_pos += current_ota_data->total_len;
3677 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_OUTPUT_GID(current_ota_data->global_id);
3678 mcf_dump_data(KAL_FALSE, &current_ota_data->buff_start + current_ota_data->array_index_len, current_ota_data->value_len);
3679 }
3680 else if (type == MCF_TYPE_OTA_BY_OP)
3681 {
3682 mcf_tool_gid_tlvota_file_item_t *current_ota_by_data = current_node->data;
3683 kal_mem_cpy(current_pos, current_ota_by_data, current_ota_by_data->total_len);
3684 current_pos += current_ota_by_data->total_len;
3685 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_OUTPUT_GID(current_ota_by_data->global_id);
3686 mcf_dump_data(KAL_FALSE, &current_ota_by_data->buff_start + current_ota_by_data->tag_len + current_ota_by_data->array_index_len, current_ota_by_data->value_len);
3687 }
3688 current_node = current_node->next_node;
3689 output_header->item_num++;
3690 output_header->file_size = (kal_uint32)((kal_uint8 *)current_pos - (kal_uint8 *)output_header);
3691 if (output_header->file_size > output_buffer_size)
3692 {
3693 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_OUTPUT_BUFFER_OUT_OF_SIZE(output_header->file_size, output_buffer_size);
3694 if (coreID == 0){
3695 SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1);
3696 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID);
3697 }
3698 return KAL_FALSE;
3699 }
3700 }
3701
3702 if ((output_header->operation_mask & MCF_FILE_OP_AES_128) || (output_header->operation_mask & MCF_FILE_OP_AES_256))
3703 {
3704 if (((output_header->file_size - output_header->total_len) % 16) != 0)
3705 output_header->file_size += 16 - (output_header->file_size - output_header->total_len) % 16; // content should be 16 bytes alignment
3706 }
3707 else if (((output_header->file_size - output_header->total_len) % 4) != 0)
3708 {
3709 output_header->file_size += 4 - (output_header->file_size - output_header->total_len) % 4; // content should be 4 bytes alignment
3710 }
3711
3712 }
3713
3714 // ========== security ==========
3715 {
3716 mcf_tool_file_info_t *file_header = (mcf_tool_file_info_t *)output_buffer;
3717 // checksum
3718 if (file_header->operation_mask & MCF_FILE_OP_CHECKSUM)
3719 {
3720 file_header->checksum = 0;
3721 file_header->checksum = mcf_calc_check_sum((kal_uint32 *)output_buffer, file_header->file_size);
3722 }
3723 // encrypt
3724 if (file_header->operation_mask & MCF_FILE_OP_AES_128)
3725 {
3726 kal_char password[MCF_MAX_PASSWORD_LEN] = {0};
3727 mcf_get_custom_aes_password(password);
3728 if (mcf_encrypt_128bit(password, (kal_char *)((kal_uint8 *)file_header + file_header->total_len), (file_header->file_size - file_header->total_len)) == KAL_FALSE)
3729 {
3730 if (coreID == 0){
3731 SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1);
3732 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID);
3733 }
3734 return KAL_FALSE;
3735 }
3736 }
3737 else if (file_header->operation_mask & MCF_FILE_OP_AES_256)
3738 {
3739 kal_char password[MCF_MAX_PASSWORD_LEN] = {0};
3740 mcf_get_custom_aes_password(password);
3741 if (mcf_encrypt_256bit(password, (kal_char *)((kal_uint8 *)file_header + file_header->total_len), (file_header->file_size - file_header->total_len)) == KAL_FALSE)
3742 {
3743 if (coreID == 0){
3744 SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1);
3745 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID);
3746 }
3747 return KAL_FALSE;
3748 }
3749 }
3750 }
3751
3752 mcf_merge_link_list_free(head);
3753 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_END();
3754 if (coreID == 0){
3755 SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1);
3756 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID);
3757 }
3758 return KAL_TRUE;
3759}
3760
3761// NOTE : if this gid needs to merge to a file, call mcf_merge_ota_buffer to combine this buffer
3762kal_bool mcf_merge_one_gid(void *new_gid, mcf_ota_type_enum type, void *output_buffer, kal_uint32 output_buffer_size, kal_uint32 operation_mask)
3763{
3764 MD_TRC_MCF_TR_MERGE_ONE_GID_START();
3765 if (new_gid == NULL || output_buffer == NULL) {
3766 MD_TRC_MCF_TR_MERGE_ONE_GID_INPUT_PARAM_ERROR((kal_uint32)new_gid, (kal_uint32)output_buffer);
3767 return KAL_FALSE;
3768 }
3769
3770 mcf_tool_file_info_t copy_header;
3771 mcf_tool_file_info_t *output_header = (mcf_tool_file_info_t *)output_buffer;
3772 kal_uint32 gid_size = 0;
3773 copy_header.file_version = 3;
3774 copy_header.operation_mask = operation_mask;
3775 mcf_merge_make_ota_file_header(output_header, &copy_header); // copy first header to output header
3776 if (type == MCF_TYPE_OTA)
3777 {
3778 strcpy(output_header->file_type, MCF_FILE_TYPE_OTA);
3779 mcf_tool_gid_ota_file_item_t *ota = new_gid;
3780 gid_size = ota->total_len;
3781 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_OUTPUT_GID(ota->global_id);
3782 mcf_dump_data(KAL_FALSE, &ota->buff_start + ota->array_index_len, ota->value_len);
3783 }
3784 else if (type == MCF_TYPE_OTA_BY_OP)
3785 {
3786 strcpy(output_header->file_type, MCF_FILE_TYPE_TLVOTA);
3787 mcf_tool_gid_tlvota_file_item_t *ota_by_op = new_gid;
3788 gid_size = ota_by_op->total_len;
3789 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_OUTPUT_GID(ota_by_op->global_id);
3790 mcf_dump_data(KAL_FALSE, &ota_by_op->buff_start + ota_by_op->tag_len + ota_by_op->array_index_len, ota_by_op->value_len);
3791 }
3792 else
3793 {
3794 return KAL_FALSE;
3795 }
3796 // check buffer size
3797 if ((output_header->total_len + gid_size) > output_buffer_size) {
3798 MD_TRC_MCF_TR_MERGE_OTA_BUFFER_OUTPUT_BUFFER_OUT_OF_SIZE((output_header->total_len + gid_size), output_buffer_size);
3799 return KAL_FALSE;
3800 }
3801
3802 kal_mem_cpy((kal_uint8 *)output_buffer + output_header->total_len, new_gid, gid_size);
3803 output_header->item_num = 1;
3804 output_header->file_size = (kal_uint32)((kal_uint8 *)output_buffer + output_header->total_len + gid_size - (kal_uint8 *)output_header);
3805 if (((output_header->file_size - output_header->total_len) % 4) != 0)
3806 output_header->file_size += 4 - (output_header->file_size - output_header->total_len) % 4; // content should be 16 bytes alignment
3807 // ========== security ==========
3808 {
3809 mcf_tool_file_info_t *file_header = (mcf_tool_file_info_t *)output_buffer;
3810 // checksum
3811 if (file_header->operation_mask & MCF_FILE_OP_CHECKSUM)
3812 {
3813 file_header->checksum = 0;
3814 file_header->checksum = mcf_calc_check_sum((kal_uint32 *)output_buffer, file_header->file_size);
3815 }
3816 // encrypt
3817 if (file_header->operation_mask & MCF_FILE_OP_AES_128 || file_header->operation_mask & MCF_FILE_OP_AES_256)
3818 {
3819 // this output is temp buffer, no need to encrypt
3820 file_header->operation_mask &= ~(MCF_FILE_OP_AES_128);
3821 file_header->operation_mask &= ~(MCF_FILE_OP_AES_256);
3822 }
3823 }
3824 MD_TRC_MCF_TR_MERG_ONE_GID_END();
3825 return KAL_TRUE;
3826}
3827#endif
3828
3829// password will be auto padding to 32B
3830// content should be padding to 32B alignment
3831// conrent length should be mod by 32
3832kal_bool mcf_encrypt_256bit(char *password, char *content, kal_uint32 content_length)
3833{
3834 kal_uint8 iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
3835 kal_uint8 copy_len = 0;
3836 kal_uint32 output_len;
3837 t_cust_chl_sym_key key;
3838 AES_PARAM aes_param;
3839 kal_uint32 ret = CUST_CHL_ERROR_NONE;
3840 kal_uint32 start_time = ust_get_current_time();
3841
3842 kal_mem_set(&aes_param, 0, sizeof(AES_PARAM));
3843
3844 if (content == NULL) return KAL_FALSE;
3845 if (content_length % 16 != 0) return KAL_FALSE;
3846
3847 copy_len = strlen(password);
3848 if (copy_len > 32) copy_len = 32;
3849
3850 key.m_key_len = 32;
3851 kal_mem_set(key.m_key, 0, sizeof(key.m_key));
3852 kal_mem_cpy(&key.m_key, password, copy_len);
3853 aes_param.IVLength = 16;
3854 aes_param.IV = iv;
3855 ret = CustCHL_AES_Encrypt_data(CUST_CHL_ALG_AES256, CUST_CHL_MODE_CBC, content_length, (kal_uint8 *)content, &output_len, (kal_uint8 *)content, &key, &aes_param);
3856
3857 MD_TRC_MCF_TR_ENCRYPT(ust_us_duration(start_time, ust_get_current_time()));
3858 if (ret != CUST_CHL_ERROR_NONE)
3859 return KAL_FALSE;
3860
3861 return KAL_TRUE;
3862}
3863
3864// password will be auto padding to 32B
3865// content should be padding to 32B alignment
3866// conrent length should be mod by 32
3867kal_bool mcf_decrypt_256bit(char *password, char *content, kal_uint32 content_length)
3868{
3869 kal_uint8 iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
3870 kal_uint8 copy_len = 0;
3871 kal_uint32 output_len;
3872 t_cust_chl_sym_key key;
3873 AES_PARAM aes_param;
3874 kal_uint32 ret = CUST_CHL_ERROR_NONE;
3875 kal_uint32 start_time = ust_get_current_time();
3876
3877 kal_mem_set(&aes_param, 0, sizeof(AES_PARAM));
3878
3879 if (content == NULL) return KAL_FALSE;
3880 if (content_length % 16 != 0) return KAL_FALSE;
3881
3882 copy_len = strlen(password);
3883 if (copy_len > 32) copy_len = 32;
3884
3885 key.m_key_len = 32;
3886 kal_mem_set(key.m_key, 0, sizeof(key.m_key));
3887 kal_mem_cpy(&key.m_key, password, copy_len);
3888 aes_param.IVLength = 16;
3889 aes_param.IV = iv;
3890 ret = CustCHL_AES_Decrypt_data(CUST_CHL_ALG_AES256, CUST_CHL_MODE_CBC, content_length, (kal_uint8 *)content, &output_len, (kal_uint8 *)content, &key, &aes_param);
3891
3892 MD_TRC_MCF_TR_DECRYPT(ust_us_duration(start_time, ust_get_current_time()));
3893 if (ret != CUST_CHL_ERROR_NONE)
3894 return KAL_FALSE;
3895
3896 return KAL_TRUE;
3897}
3898
3899// digest verify
3900kal_bool mcf_verify_digest(kal_uint32 digest_tag, mcf_tool_file_info_t *ota_file, mcf_digest *sign)
3901{
3902 kal_uint32 ret = KAL_FALSE;
3903 t_cust_chl_asym_key key;
3904
3905 if (digest_tag == MCF_FILE_OP_SHA256_RSA2048) {
3906 ret = mcf_get_custom_digest_public_key(sign->sequence, &key);
3907 if (ret == KAL_FALSE) return KAL_FALSE;
3908 ret = CustCHL_Verify_RSA_Signature(CUST_CHL_ALG_RSA_PKCS1_V15_SHA256_ASN1, (kal_uint8 *)ota_file, ota_file->file_size, sign->digest_value, sign->digest_len, &key);
3909 }
3910 else if(digest_tag == MCF_FILE_OP_SHA384_RSA3072){
3911 ret = mcf_get_custom_digest_public_key(sign->sequence, &key);
3912 if (ret == KAL_FALSE) return KAL_FALSE;
3913 ret = CustCHL_Verify_RSA_Signature(CUST_CHL_ALG_RSA_PKCS1_V15_SHA384_ASN1, (kal_uint8 *)ota_file, ota_file->file_size, sign->digest_value, sign->digest_len, &key);
3914 }
3915 else
3916 {
3917 // not support
3918 return KAL_FALSE;
3919 }
3920
3921 if (ret != CUST_CHL_ERROR_NONE)
3922 return KAL_FALSE;
3923
3924 return KAL_TRUE;
3925}
3926
3927void mcf_make_file_info(mcf_file_info_t *file_info, kal_uint8 path_type, kal_char *name, kal_char *sw_version, kal_uint8 sw_version_len, kal_char *gen_time, kal_uint8 gen_time_len, kal_uint64 last_mod_time, kal_uint32 checksum)
3928{
3929 MD_TRC_MCF_TR_MAKE_FILE_INFO_START(path_type, last_mod_time & 0xFFFFFFFF, checksum & 0xFFFFFFFF);
3930
3931 kal_mem_set(file_info, 0, sizeof(mcf_file_info_t));
3932 file_info->path_type = path_type;
3933 strncpy(file_info->name, name, MCF_FILE_MAX_NAME_LEN-1);
3934 strncpy(file_info->sw_version, sw_version, sw_version_len);
3935 strncpy(file_info->gen_time, gen_time, gen_time_len);
3936 file_info->last_mod_time = last_mod_time;
3937 file_info->checksum = checksum;
3938 file_info->sw_version_len = sw_version_len;
3939 file_info->gen_time_len = gen_time_len;
3940}
3941
3942kal_bool mcf_compare_file_info(mcf_file_info_t *old_file, mcf_file_info_t *new_file)
3943{
3944 static nvram_ef_mcf_sw_info_struct nv_sw_info;
3945
3946 MD_TRC_MCF_TR_COMPARE_FILE_INFO_START();
3947 MD_TRC_MCF_TR_COMPARE_FILE_INFO_OLD_FILE_INFO(old_file->sw_version, old_file->gen_time);
3948 MD_TRC_MCF_TR_COMPARE_FILE_INFO_NEW_FILE_INFO(new_file->sw_version, new_file->gen_time);
3949 MD_TRC_MCF_TR_COMPARE_FILE_INFO_FILE_CHECKSUM(old_file->checksum & 0xFFFFFFFF, new_file->checksum & 0xFFFFFFFF);
3950 MD_TRC_MCF_TR_COMPARE_FILE_INFO_FILE_LAST_MOD_TIME(old_file->last_mod_time & 0xFFFFFFFF, new_file->last_mod_time & 0xFFFFFFFF);
3951 if ( (strncmp(old_file->sw_version, new_file->sw_version, new_file->sw_version_len) == 0) &&
3952 (strncmp(old_file->gen_time, new_file->gen_time, new_file->gen_time_len) == 0) &&
3953 (old_file->path_type == new_file->path_type) &&
3954 (strncmp(old_file->name, new_file->name, MCF_FILE_MAX_NAME_LEN) == 0) &&
3955 (old_file->last_mod_time == new_file->last_mod_time) &&
3956 (old_file->checksum == new_file->checksum) ) {
3957
3958 if ( !nvram_external_read_data(NVRAM_EF_MCF_SW_INFO_LID, 1, (kal_uint8 *)&nv_sw_info, sizeof(nvram_ef_mcf_sw_info_struct))) {
3959 MD_TRC_MCF_TR_COMPARE_FILE_INFO_READ_FILE_NVRAM_FAIL(NVRAM_EF_MCF_SW_INFO_LID);
3960 return KAL_FALSE;
3961 }
3962
3963 if ((strncmp(nv_sw_info.version, release_verno(), MCF_SW_VERNO_LEN) == 0) &&
3964 (strncmp(nv_sw_info.build_time, build_date_time(), MCF_SW_BUILD_TIME_LEN) == 0)){
3965 MD_TRC_MCF_TR_COMPARE_FILE_INFO_MD_INFO(nv_sw_info.version, nv_sw_info.build_time);
3966 return KAL_TRUE;
3967 }else{
3968 MD_TRC_MCF_TR_COMPARE_FILE_INFO_FILE_NOT_THE_SAME();
3969 return KAL_FALSE;
3970 }
3971 }else{
3972 MD_TRC_MCF_TR_COMPARE_FILE_INFO_FILE_NOT_THE_SAME();
3973 return KAL_FALSE;
3974
3975 }
3976
3977}
3978