| /***************************************************************************** |
| * Copyright Statement: |
| * -------------------- |
| * This software is protected by Copyright and the information contained |
| * herein is confidential. The software may not be copied and the information |
| * contained herein may not be used or disclosed except with the written |
| * permission of MediaTek Inc. (C) 2018 |
| * |
| * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES |
| * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") |
| * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON |
| * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, |
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. |
| * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE |
| * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR |
| * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH |
| * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO |
| * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S |
| * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. |
| * |
| * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE |
| * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, |
| * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, |
| * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO |
| * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. |
| * |
| * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE |
| * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF |
| * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND |
| * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER |
| * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC). |
| * |
| *****************************************************************************/ |
| |
| /******************************************************************************* |
| * Filename: |
| * --------- |
| * mcf_util.c |
| * |
| * Project: |
| * -------- |
| * UMOLYA |
| * |
| * Description: |
| * ------------ |
| * MD Configuration Framework internal utility. |
| * |
| * Author: |
| * ------- |
| * ------- |
| * |
| *============================================================================== |
| * HISTORY |
| * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!! |
| *------------------------------------------------------------------------------ |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| *------------------------------------------------------------------------------ |
| * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!! |
| *============================================================================== |
| *******************************************************************************/ |
| |
| #include "kal_public_api.h" |
| #include "fs_general_api.h" |
| |
| #include "mcf_custom.h" |
| #include "mcf_defs.h" |
| #include "mcf_debug.h" |
| #include "mcf_struct.h" |
| #include "mcf_util.h" |
| #include "mcf_object.h" |
| #include "cust_chl_interface.h" |
| #include "us_timer.h" |
| #include <stdarg.h> |
| #include "sleepdrv_interface.h" |
| |
| /*------------------------------------------------------------------------------ |
| * Global variables. |
| *----------------------------------------------------------------------------*/ |
| mcf_t mcf_inst_g; |
| kal_enhmutexid mcf_enhmutex_g = NULL; |
| event_scheduler *mcf_timer_es_g = NULL; |
| eventid mcf_timer_eventid_g = NULL; |
| mcf_common_t com_Mcf; |
| kal_enhmutexid mcf_utfwk_enhmutex_g = NULL; |
| mcf_file_info_t new_file_info; |
| mcf_file_info_t old_file_info; |
| |
| #undef BOOT_TRC_MSG |
| #define BOOT_TRC_MSG(_name,_format) {_format}, |
| static MCF_BOOT_LOG boot_trace_format[] = |
| { |
| #include "mcf_boot_trace.h" |
| }; |
| |
| /*------------------------------------------------------------------------------ |
| * Helper macro. |
| *----------------------------------------------------------------------------*/ |
| |
| /*------------------------------------------------------------------------------ |
| * Private data structure. |
| *----------------------------------------------------------------------------*/ |
| |
| /*------------------------------------------------------------------------------ |
| * Private variables. |
| *----------------------------------------------------------------------------*/ |
| static KAL_ADM_ID mcf_mem_id = NULL; |
| static kal_uint8 mcf_mem_pool[MCF_MAX_MEM_MALLOC_SIZE]; |
| static kal_bool mcf_mem_init_flag = KAL_FALSE; |
| /*------------------------------------------------------------------------------ |
| * Private fucntions. |
| *----------------------------------------------------------------------------*/ |
| extern kal_char* release_verno(void); |
| extern kal_char* build_date_time(void); |
| /*------------------------------------------------------------------------------ |
| * Public fucntions. |
| *----------------------------------------------------------------------------*/ |
| #if !defined(__HIF_CCCI_SUPPORT__) || !defined(__MTK_TARGET__) |
| kal_int32 MCF_dummy_FS_CMPT_Read(const WCHAR * FileName, NVRAM_FS_PARAM_CMPT_T* nvram_param) |
| { |
| return FS_NO_ERROR; |
| } |
| #include <stdio.h> |
| #include <windows.h> |
| kal_int32 MCF_Win_FS_CMPT_Read(const WCHAR * FileName, NVRAM_FS_PARAM_CMPT_T* nvram_param) |
| { |
| char fname[MCF_FILE_MAX_NAME_LEN] = { 0 }; |
| char fullpath[MCF_FILE_MAX_MD_PATH_LEN + MCF_FILE_MAX_NAME_LEN] = { 0 }; |
| kal_uint32 i = 0; |
| FILE *fd = NULL; |
| if (mcf_utfwk_is_working_status == KAL_TRUE){ |
| return FS_NO_ERROR; |
| } |
| |
| // translate wchar to char |
| WCHAR *ptr = FileName; // skip drive "S:" |
| while (*ptr != NULL) { |
| fname[i++] = (char)*ptr; |
| ptr++; |
| } |
| |
| if (GetModuleFileName(NULL, fullpath, MCF_FILE_MAX_MD_PATH_LEN + MCF_FILE_MAX_NAME_LEN) != NULL) { |
| char *pch = strrchr(fullpath, '\\'); |
| *(++pch) = 0; |
| strncat(fullpath, fname, MCF_FILE_MAX_MD_PATH_LEN + MCF_FILE_MAX_NAME_LEN - 1); |
| } |
| else { |
| return FS_FILE_NOT_FOUND; |
| } |
| |
| // due to open & close operation are must, so always open & close file (ignore CCCI_FS_CMPT_OPEN & CCCI_FS_CMPT_CLOSE) |
| fd = fopen(fullpath, "rb"); |
| if (fd == NULL) |
| return FS_FILE_NOT_FOUND; |
| //get file size |
| if (nvram_param->opid_map & CCCI_FS_CMPT_GETFILESIZE) |
| { |
| fseek(fd, 0, SEEK_END); |
| *nvram_param->FileSize = ftell(fd); |
| fseek(fd, 0, SEEK_SET); |
| } |
| // seek |
| if (nvram_param->opid_map & CCCI_FS_CMPT_SEEK) |
| { |
| fseek(fd, nvram_param->Offset, nvram_param->Whence); |
| } |
| // read |
| if (nvram_param->opid_map & CCCI_FS_CMPT_READ) |
| { |
| if (nvram_param->DataPtr != NULL) { |
| *nvram_param->Read = fread(nvram_param->DataPtr, nvram_param->Length, 1, fd); |
| } |
| } |
| fclose(fd); |
| return FS_NO_ERROR; |
| } |
| #endif |
| |
| void mcf_mem_init(void) |
| { |
| if (mcf_mem_init_flag == KAL_FALSE) |
| { |
| mcf_mem_id = kal_adm_create((void*)mcf_mem_pool, sizeof(mcf_mem_pool), NULL, KAL_FALSE); |
| mcf_mem_init_flag = KAL_TRUE; |
| } |
| } |
| |
| void *mcf_malloc(unsigned int size) |
| { |
| mcf_mem_init(); |
| if (NULL != mcf_mem_id) { |
| void *ret = kal_adm_alloc(mcf_mem_id, size); |
| if(ret == NULL) |
| { |
| MCF_BOOT_TRACE(MCF_BOOT_TR_ALLOC_MEM_ERROR); |
| MD_TRC_MCF_TR_ALLOC_MEM_ERROR(); |
| } |
| return ret; |
| } |
| return NULL; |
| } |
| |
| void mcf_free(void *ptr) |
| { |
| if (NULL == mcf_mem_id) { |
| return; |
| } |
| kal_adm_free(mcf_mem_id, ptr); |
| } |
| |
| void mcf_create_custom_folder(mcf_t *pMcf) |
| { |
| kal_wchar foldername[MCF_FILE_MAX_MD_PATH_LEN] = {0}; |
| kal_int32 fs_api_ret; |
| |
| kal_wsprintf(foldername, "%s\0", MCF_FS_CUSTOM_FOLDER_PATH); |
| fs_api_ret = FS_CreateDir(foldername); |
| if (fs_api_ret < FS_NO_ERROR) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_CREATE_CUSTOM_FOLDER_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_CREATE_CUSTOM_FOLDER_FAIL, MCF_FS_CUSTOM_FOLDER_PATH, fs_api_ret); |
| } |
| |
| return; |
| } |
| |
| mcf_ota_result_e mcf_read_ota_file( |
| kal_bool is_booting, |
| kal_char *req_fs_root_path, |
| kal_char *req_file_path_name, |
| l4c_mcf_path_type_enum *apply_path_type, |
| kal_char *apply_filename, |
| mcf_t *pMcf) |
| { |
| NVRAM_FS_PARAM_CMPT_T fs_cmpt; |
| FS_FileDetail fs_file_detail[L4C_MCF_PATH_TYPE_MAX] = {0}; |
| kal_uint32 read_byte = 0; |
| kal_uint32 file_size = 0; |
| mcf_ota_result_e ret = MCF_OTA_R_SUCCESS; |
| mcf_ota_file_t *ota_file = &(pMcf->ota_file); |
| kal_wchar filename[MCF_FILE_MAX_MD_PATH_LEN + MCF_FILE_MAX_NAME_LEN]; |
| mcf_tool_file_info_t *pFile; |
| kal_char password[MCF_MAX_PASSWORD_LEN] = {0}; |
| kal_bool is_get_custom_filename = KAL_FALSE; |
| kal_bool is_default_path; |
| kal_uint32 dummy_para; |
| kal_int32 fs_api_ret[L4C_MCF_PATH_TYPE_MAX]; |
| kal_uint64 last_mod_time = 0; |
| kal_char default_file_name_tag[30]; |
| kal_uint64 ini_path_ota_file_last_mod_time = 0; |
| kal_uint64 ini_path_runtime_file_last_mod_time = 0; |
| kal_char ini_root_path[20]; |
| |
| fs_cmpt.opid_map = NVRAM_FS_CMPT_OPEN | NVRAM_FS_CMPT_GETFILESIZE | NVRAM_FS_CMPT_CLOSE; |
| fs_cmpt.Flag = FS_READ_ONLY; |
| fs_cmpt.Length = 0; |
| fs_cmpt.Offset = 0; |
| fs_cmpt.Whence = FS_FILE_BEGIN; |
| fs_cmpt.DataPtr = &dummy_para; |
| fs_cmpt.Read = &dummy_para; |
| fs_cmpt.FileSize = &file_size; |
| |
| if ( (strcmp(req_fs_root_path, "") != 0) && (strcmp(req_file_path_name, "") != 0) ) { |
| if (strcmp(req_fs_root_path, MCF_FS_DEFAULT_FOLDER_PATH) == 0) { |
| *apply_path_type = L4C_MCF_PATH_TYPE_OTA; |
| } else if (strcmp(req_fs_root_path, MCF_FS_CUSTOM_FOLDER_PATH) == 0) { |
| *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME; |
| }else{ |
| MD_TRC_MCF_TR_READ_OTA_FILE_INVALID_PATH(req_fs_root_path); |
| ret = MCF_OTA_R_INVALID_PARAMETER; |
| |
| return ret; |
| } |
| kal_wsprintf(filename, "%s\\%s\0", req_fs_root_path, req_file_path_name); |
| strncpy(apply_filename, req_file_path_name, MCF_FILE_MAX_NAME_LEN - 1); |
| is_default_path = KAL_FALSE; |
| } else { |
| is_get_custom_filename = mcf_get_custom_file_path_name((kal_uint8 *)apply_path_type, apply_filename); |
| strncpy(default_file_name_tag, "Default_OTA_File_Name", 29); |
| if (is_get_custom_filename == KAL_TRUE) { |
| if (*apply_path_type >= L4C_MCF_PATH_TYPE_MAX || *apply_path_type < 0) { |
| MD_TRC_MCF_TR_READ_OTA_FILE_INVALID_PATH_TYPE(*apply_path_type); |
| ret = MCF_OTA_R_INVALID_PARAMETER; |
| |
| return ret; |
| } |
| |
| if (*apply_path_type == L4C_MCF_PATH_TYPE_OTA) { |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, apply_filename); |
| } else if (*apply_path_type == L4C_MCF_PATH_TYPE_RUNTIME) { |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, apply_filename); |
| } |
| } |
| else { |
| /* Try to read default ota file name in INI file */ |
| /* Compare modified time of ini file to select which file to be applied */ |
| 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){ |
| ini_path_ota_file_last_mod_time = 0; |
| MD_TRC_MCF_TR_READ_OTA_FILE_READ_INI_FILE_FAIL(L4C_MCF_PATH_TYPE_OTA, MCF_OTA_R_READ_OTA_FILE_FAIL); |
| |
| 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){ |
| ini_path_runtime_file_last_mod_time = 0; |
| MD_TRC_MCF_TR_READ_OTA_FILE_READ_INI_FILE_FAIL(L4C_MCF_PATH_TYPE_RUNTIME, MCF_OTA_R_READ_OTA_FILE_FAIL); |
| } |
| } |
| |
| 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){ |
| ini_path_runtime_file_last_mod_time = 0; |
| MD_TRC_MCF_TR_READ_OTA_FILE_READ_INI_FILE_FAIL(L4C_MCF_PATH_TYPE_RUNTIME, MCF_OTA_R_READ_OTA_FILE_FAIL); |
| |
| 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){ |
| ini_path_ota_file_last_mod_time = 0; |
| MD_TRC_MCF_TR_READ_OTA_FILE_READ_INI_FILE_FAIL(L4C_MCF_PATH_TYPE_OTA, MCF_OTA_R_READ_OTA_FILE_FAIL); |
| } |
| } |
| |
| kal_mem_set(ini_root_path,0,20); |
| if (ini_path_ota_file_last_mod_time > ini_path_runtime_file_last_mod_time){ |
| strncpy(ini_root_path,MCF_FS_DEFAULT_FOLDER_PATH, 19); |
| }else{ |
| strncpy(ini_root_path,MCF_FS_CUSTOM_FOLDER_PATH, 19); |
| } |
| if (mcf_read_ini_file(ini_root_path , MCF_FS_DEFAULT_INI_FILE_NAME, apply_path_type, apply_filename, pMcf) == MCF_OTA_R_SUCCESS && |
| mcf_find_ini_item((kal_char *)pMcf->ini_file.buff, default_file_name_tag, apply_filename, pMcf) == KAL_TRUE && strcmp(apply_filename, "") != 0) { |
| strncat (apply_filename,".mcfota", MCF_FILE_MAX_NAME_LEN - 1); |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, apply_filename); |
| MCF_BOOT_TRACE(MCF_BOOT_TR_DO_OTA_FULL_GET_DEFAULT_OTA_FILE_NAME_FROM_INI, apply_filename); |
| |
| }else{ |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_DEFAULT_OTA_FILE_NAME); |
| strncpy(apply_filename, MCF_FS_DEFAULT_OTA_FILE_NAME, MCF_FILE_MAX_NAME_LEN - 1); |
| } |
| |
| /* Compare modified time of OTA file to select which file to be applied */ |
| fs_api_ret[L4C_MCF_PATH_TYPE_OTA] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_OTA]); |
| MD_TRC_MCF_TR_READ_OTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_OTA, fs_api_ret[L4C_MCF_PATH_TYPE_OTA], |
| (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)); |
| if (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] != FS_NO_ERROR) { |
| kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_OTA], 0, sizeof(FS_FileDetail)); |
| } |
| |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_DEFAULT_OTA_FILE_NAME); |
| fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME]); |
| MD_TRC_MCF_TR_READ_OTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_RUNTIME, fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME], |
| (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)); |
| if (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] != FS_NO_ERROR) { |
| kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME], 0, sizeof(FS_FileDetail)); |
| } |
| |
| if ( (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] == FS_NO_ERROR) || (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] == FS_NO_ERROR) ) { |
| if (fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime > fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime) { |
| *apply_path_type = L4C_MCF_PATH_TYPE_OTA; |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, apply_filename); |
| } else { |
| *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME; |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_DEFAULT_OTA_FILE_NAME); |
| } |
| } else { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_COMPARE_FAIL); |
| } |
| MD_TRC_MCF_TR_READ_OTA_FILE_COMPARE_FAIL(); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| |
| } |
| is_default_path = KAL_TRUE; |
| } |
| |
| fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt); |
| if (fs_api_ret[0] < FS_NO_ERROR) { |
| if (is_booting == KAL_TRUE) { |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_FAIL, *apply_path_type, fs_api_ret[0]); |
| MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_OTA_FILE_FAIL(*apply_path_type, fs_api_ret[0]); |
| dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename); |
| |
| /* If cannot read given OTA file, read default OTA file */ |
| if (is_default_path == KAL_FALSE) { |
| is_get_custom_filename = mcf_get_custom_file_path_name((kal_uint8 *)apply_path_type, apply_filename); |
| if (*apply_path_type >= L4C_MCF_PATH_TYPE_MAX || *apply_path_type < 0) { |
| MD_TRC_MCF_TR_READ_OTA_FILE_INVALID_PATH_TYPE(*apply_path_type); |
| ret = MCF_OTA_R_INVALID_PARAMETER; |
| |
| return ret; |
| } |
| |
| if (is_get_custom_filename == KAL_TRUE) { |
| if (*apply_path_type == L4C_MCF_PATH_TYPE_OTA) { |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, apply_filename); |
| } else if (*apply_path_type == L4C_MCF_PATH_TYPE_RUNTIME) { |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, apply_filename); |
| } |
| } else { |
| /* Compare modified time of OTA file to select which file to be applied */ |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_DEFAULT_OTA_FILE_NAME); |
| fs_api_ret[L4C_MCF_PATH_TYPE_OTA] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_OTA]); |
| MD_TRC_MCF_TR_READ_OTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_OTA, fs_api_ret[L4C_MCF_PATH_TYPE_OTA], |
| (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)); |
| if (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] != FS_NO_ERROR) { |
| kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_OTA], 0, sizeof(FS_FileDetail)); |
| } |
| |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_DEFAULT_OTA_FILE_NAME); |
| fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME]); |
| MD_TRC_MCF_TR_READ_OTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_RUNTIME, fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME], |
| (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)); |
| if (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] != FS_NO_ERROR) { |
| kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME], 0, sizeof(FS_FileDetail)); |
| } |
| |
| if ( (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] == FS_NO_ERROR) || (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] == FS_NO_ERROR) ) { |
| if (fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime > fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime) { |
| *apply_path_type = L4C_MCF_PATH_TYPE_OTA; |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_DEFAULT_OTA_FILE_NAME); |
| } else { |
| *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME; |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_DEFAULT_OTA_FILE_NAME); |
| } |
| } else { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_COMPARE_FAIL); |
| } |
| MD_TRC_MCF_TR_READ_OTA_FILE_COMPARE_FAIL(); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| |
| strncpy(apply_filename, MCF_FS_DEFAULT_OTA_FILE_NAME, MCF_FILE_MAX_NAME_LEN - 1); |
| |
| } |
| |
| fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt); |
| if (fs_api_ret[0] < FS_NO_ERROR) { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_FAIL, *apply_path_type, fs_api_ret[0]); |
| MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_OTA_FILE_FAIL(*apply_path_type, fs_api_ret[0]); |
| dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| } else { |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| } |
| |
| if (file_size > MCF_MAX_OTA_FILE_SIZE) { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_OTA_FILE_OVERSIZE; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_OVERSIZE, file_size, MCF_MAX_OTA_FILE_SIZE); |
| } |
| MD_TRC_MCF_TR_READ_OTA_FILE_OVERSIZE(file_size, MCF_MAX_OTA_FILE_SIZE); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| |
| /* Read file */ |
| fs_cmpt.opid_map = NVRAM_FS_CMPT_OPEN | NVRAM_FS_CMPT_READ | NVRAM_FS_CMPT_CLOSE; |
| fs_cmpt.Flag = FS_READ_ONLY; |
| fs_cmpt.Length = file_size; |
| fs_cmpt.Offset = 0; |
| fs_cmpt.Whence = FS_FILE_BEGIN; |
| fs_cmpt.DataPtr = ota_file->buff; |
| fs_cmpt.Read = &read_byte; |
| fs_cmpt.FileSize = &dummy_para; |
| |
| fs_api_ret[*apply_path_type] = FS_GetFileDetail(filename, &fs_file_detail[*apply_path_type]); |
| MD_TRC_MCF_TR_READ_OTA_FILE_MODIFIED_TIME(*apply_path_type, fs_api_ret[*apply_path_type], |
| (kal_uint32)((fs_file_detail[*apply_path_type].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[*apply_path_type].LastStatusChangeTime & 0xFFFFFFFF)); |
| if (fs_api_ret[*apply_path_type] == FS_NO_ERROR) { |
| last_mod_time = fs_file_detail[*apply_path_type].LastStatusChangeTime; |
| } else { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_FAIL, *apply_path_type, fs_api_ret[*apply_path_type]); |
| MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_OTA_FILE_FAIL(*apply_path_type, fs_api_ret[*apply_path_type]); |
| dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| |
| MCF_W_LOCK_OBJECT(ota_file, mcf_enhmutex_g); |
| if (ota_file) { |
| fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt); |
| if (fs_api_ret[0] < FS_NO_ERROR) { |
| MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_FAIL, *apply_path_type, fs_api_ret[0]); |
| MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_OTA_FILE_FAIL(*apply_path_type, fs_api_ret[0]); |
| dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| |
| pFile = (mcf_tool_file_info_t *)(ota_file->buff); |
| #ifdef __MCF_FIND_TAG_SUPPORT__ |
| if (pFile->file_version == 2 || pFile->file_version == 3) { |
| #else |
| if (pFile->file_version == 3) { |
| #endif |
| kal_uint32 operation_mask = 0; |
| |
| /* Check custom operation mask */ |
| operation_mask = mcf_get_custom_operation_mask(); |
| if ((pFile->operation_mask & operation_mask) != operation_mask) { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_OPERATION_MASK_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_OPERATION_MASK_FAIL, apply_filename, pFile->operation_mask, operation_mask); |
| } |
| MD_TRC_MCF_TR_READ_OTA_FILE_OPERATION_MASK_FAIL(apply_filename, pFile->operation_mask, operation_mask); |
| ret = MCF_OTA_R_INVALID_FILE; |
| |
| kal_mem_set(ota_file->buff, 0, MCF_MAX_OTA_FILE_SIZE); |
| kal_mem_set(ota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| ota_file->path_type = 0; |
| ota_file->last_mod_time = 0; |
| MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g); |
| |
| return ret; |
| } |
| |
| /* First check digest first |
| * If file is encrypted and has checksum. |
| * Decrypt file before checking checksum. |
| */ |
| |
| // RSA verify digest |
| if ((pFile->operation_mask & MCF_FILE_OP_SHA256_RSA2048) != 0) { |
| |
| 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) { |
| kal_mem_set(ota_file->buff, 0, MCF_MAX_OTA_FILE_SIZE); |
| kal_mem_set(ota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| ota_file->path_type = 0; |
| ota_file->last_mod_time = 0; |
| MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DIGEST_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_DIGEST_FAIL, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_OTA_FILE_DIGEST_FAIL(apply_filename); |
| ret = MCF_OTA_R_DIGEST_FAIL; |
| |
| return ret; |
| } |
| |
| } |
| |
| else if ((pFile->operation_mask & MCF_FILE_OP_SHA384_RSA3072) != 0) { |
| |
| 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) { |
| kal_mem_set(ota_file->buff, 0, MCF_MAX_OTA_FILE_SIZE); |
| kal_mem_set(ota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| ota_file->path_type = 0; |
| ota_file->last_mod_time = 0; |
| MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DIGEST_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_DIGEST_FAIL, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_OTA_FILE_DIGEST_FAIL(apply_filename); |
| ret = MCF_OTA_R_DIGEST_FAIL; |
| |
| return ret; |
| } |
| |
| } |
| |
| if ( (pFile->operation_mask & MCF_FILE_OP_AES_128) != 0) { |
| mcf_get_custom_aes_password(password); |
| |
| if (mcf_decrypt_128bit(password, (kal_char *)(ota_file->buff + pFile->total_len), (pFile->file_size - pFile->total_len) ) != KAL_TRUE) { |
| kal_mem_set(ota_file->buff, 0, MCF_MAX_OTA_FILE_SIZE); |
| kal_mem_set(ota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| ota_file->path_type = 0; |
| ota_file->last_mod_time = 0; |
| MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DECRYPTION_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_DECRYPTION_FAIL, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_OTA_FILE_DECRYPTION_FAIL(apply_filename); |
| ret = MCF_OTA_R_DECRYPTION_FAIL; |
| |
| return ret; |
| } |
| } |
| // for AES_256 |
| else if ((pFile->operation_mask & MCF_FILE_OP_AES_256) != 0) { |
| mcf_get_custom_aes_password(password); |
| if (mcf_decrypt_256bit(password, (kal_char *)(ota_file->buff + pFile->total_len), (pFile->file_size - pFile->total_len)) != KAL_TRUE) { |
| kal_mem_set(ota_file->buff, 0, MCF_MAX_OTA_FILE_SIZE); |
| kal_mem_set(ota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| ota_file->path_type = 0; |
| ota_file->last_mod_time = 0; |
| MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DECRYPTION_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_DECRYPTION_FAIL, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_OTA_FILE_DECRYPTION_FAIL(apply_filename); |
| ret = MCF_OTA_R_DECRYPTION_FAIL; |
| |
| return ret; |
| } |
| } |
| |
| if ( (pFile->operation_mask & MCF_FILE_OP_CHECKSUM) != 0) { |
| if (mcf_check_check_sum((kal_uint32 *)(ota_file->buff), pFile->file_size) != 0) { |
| kal_mem_set(ota_file->buff, 0, MCF_MAX_OTA_FILE_SIZE); |
| kal_mem_set(ota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| ota_file->path_type = 0; |
| ota_file->last_mod_time = 0; |
| MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_CHECKSUM_ERROR; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_CHECKSUM_ERROR, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_OTA_FILE_CHECKSUM_ERROR(apply_filename); |
| ret = MCF_OTA_R_CHECKSUM_ERROR; |
| |
| return ret; |
| } |
| } |
| } else { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_INVALID_FILE; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_INVALID_FILE_VERSION, pFile->file_version); |
| } |
| MD_TRC_MCF_TR_READ_OTA_FILE_INVALID_FILE_VERSION(pFile->file_version); |
| kal_mem_set(ota_file->buff, 0, MCF_MAX_OTA_FILE_SIZE); |
| kal_mem_set(ota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| ota_file->path_type = 0; |
| ota_file->last_mod_time = 0; |
| MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g); |
| ret = MCF_OTA_R_INVALID_FILE; |
| |
| return ret; |
| } |
| |
| ota_file->path_type = *apply_path_type; |
| ota_file->last_mod_time = last_mod_time; |
| #if defined(__MCF_UT_FRAMEWORK_SUPPORT__) |
| if (strcmp(ota_file->relative_path_name, "") == 0){ |
| strncpy(ota_file->relative_path_name, apply_filename, MCF_FILE_MAX_NAME_LEN - 1); |
| }else{ |
| strncpy(apply_filename, ota_file->relative_path_name, MCF_FILE_MAX_NAME_LEN - 1); |
| } |
| #else |
| strncpy(ota_file->relative_path_name, apply_filename, MCF_FILE_MAX_NAME_LEN - 1); |
| #endif |
| MCF_W_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g); |
| } else { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_TAKE_WRITE_LOCK_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_OTA_FILE_TAKE_WRITE_LOCK_FAIL, apply_filename, *apply_path_type); |
| } |
| MD_TRC_MCF_TR_READ_OTA_FILE_TAKE_WRITE_LOCK_FAIL(apply_filename, *apply_path_type); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| } |
| |
| return ret; |
| } |
| |
| mcf_ota_result_e mcf_read_tlvota_file( |
| kal_bool is_booting, |
| kal_uint8 sim_id, |
| kal_char *req_fs_root_path, |
| kal_char *req_file_path_name, |
| l4c_mcf_path_type_enum *apply_path_type, |
| kal_char *apply_filename, |
| mcf_t *pMcf) |
| { |
| NVRAM_FS_PARAM_CMPT_T fs_cmpt; |
| FS_FileDetail fs_file_detail[L4C_MCF_PATH_TYPE_MAX] = {0}; |
| kal_uint32 read_byte = 0; |
| kal_uint32 file_size = 0; |
| mcf_ota_result_e ret = MCF_OTA_R_SUCCESS; |
| mcf_tlvota_file_t *tlvota_file = &(pMcf->tlvota_file[sim_id]); |
| kal_wchar filename[MCF_FILE_MAX_MD_PATH_LEN + MCF_FILE_MAX_NAME_LEN]; |
| mcf_tool_file_info_t *pFile; |
| kal_char password[MCF_MAX_PASSWORD_LEN] = {0}; |
| kal_bool is_default_path; |
| kal_uint32 dummy_para; |
| kal_int32 fs_api_ret[L4C_MCF_PATH_TYPE_MAX]; |
| kal_uint64 last_mod_time = 0; |
| |
| fs_cmpt.opid_map = NVRAM_FS_CMPT_OPEN | NVRAM_FS_CMPT_GETFILESIZE | NVRAM_FS_CMPT_CLOSE; |
| fs_cmpt.Flag = FS_READ_ONLY; |
| fs_cmpt.Length = 0; |
| fs_cmpt.Offset = 0; |
| fs_cmpt.Whence = FS_FILE_BEGIN; |
| fs_cmpt.DataPtr = &dummy_para; |
| fs_cmpt.Read = &dummy_para; |
| fs_cmpt.FileSize = &file_size; |
| |
| if ( (strcmp(req_fs_root_path, "") != 0) && (strcmp(req_file_path_name, "") != 0) ) { |
| if (strcmp(req_fs_root_path, MCF_FS_DEFAULT_FOLDER_PATH) == 0) { |
| *apply_path_type = L4C_MCF_PATH_TYPE_OTA; |
| } else if (strcmp(req_fs_root_path, MCF_FS_CUSTOM_FOLDER_PATH) == 0) { |
| *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME; |
| } else{ |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_INVALID_PATH(req_fs_root_path); |
| ret = MCF_OTA_R_INVALID_PARAMETER; |
| |
| return ret; |
| } |
| kal_wsprintf(filename, "%s\\%s\0", req_fs_root_path, req_file_path_name); |
| strncpy(apply_filename, req_file_path_name, MCF_FILE_MAX_NAME_LEN - 1); |
| is_default_path = KAL_FALSE; |
| } else { |
| /* Compare modified time of OP-OTA file to select which file to be applied */ |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_DEFAULT_TLVOTA_FILE_NAME); |
| fs_api_ret[L4C_MCF_PATH_TYPE_OTA] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_OTA]); |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_OTA, fs_api_ret[L4C_MCF_PATH_TYPE_OTA], |
| (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)); |
| if (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] != FS_NO_ERROR) { |
| kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_OTA], 0, sizeof(FS_FileDetail)); |
| } |
| |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_DEFAULT_TLVOTA_FILE_NAME); |
| fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME]); |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_RUNTIME, fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME], |
| (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)); |
| if (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] != FS_NO_ERROR) { |
| kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME], 0, sizeof(FS_FileDetail)); |
| } |
| |
| if ( (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] == FS_NO_ERROR) || (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] == FS_NO_ERROR) ) { |
| if (fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime > fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime) { |
| *apply_path_type = L4C_MCF_PATH_TYPE_OTA; |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_DEFAULT_TLVOTA_FILE_NAME); |
| } else { |
| *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME; |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_DEFAULT_TLVOTA_FILE_NAME); |
| } |
| } else { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_COMPARE_FAIL); |
| } |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_COMPARE_FAIL(); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| |
| strncpy(apply_filename, MCF_FS_DEFAULT_TLVOTA_FILE_NAME, MCF_FILE_MAX_NAME_LEN - 1); |
| |
| is_default_path = KAL_TRUE; |
| } |
| |
| fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt); |
| if (fs_api_ret[0] < FS_NO_ERROR) { |
| if (is_booting == KAL_TRUE) { |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_FAIL, *apply_path_type, sim_id, fs_api_ret[0]); |
| MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_FAIL(*apply_path_type, sim_id, fs_api_ret[0]); |
| dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename); |
| |
| /* If cannot read given TLV-OTA file, read default TLV-OTA file */ |
| if (is_default_path == KAL_FALSE) { |
| /* Compare modified time of OP-OTA file to select which file to be applied */ |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_DEFAULT_TLVOTA_FILE_NAME); |
| fs_api_ret[L4C_MCF_PATH_TYPE_OTA] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_OTA]); |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_OTA, fs_api_ret[L4C_MCF_PATH_TYPE_OTA], |
| (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)); |
| if (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] != FS_NO_ERROR) { |
| kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_OTA], 0, sizeof(FS_FileDetail)); |
| } |
| |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_DEFAULT_TLVOTA_FILE_NAME); |
| fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME]); |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_RUNTIME, fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME], |
| (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)); |
| if (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] != FS_NO_ERROR) { |
| kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME], 0, sizeof(FS_FileDetail)); |
| } |
| |
| if ( (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] == FS_NO_ERROR) || (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] == FS_NO_ERROR) ) { |
| if (fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime > fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime) { |
| *apply_path_type = L4C_MCF_PATH_TYPE_OTA; |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_DEFAULT_TLVOTA_FILE_NAME); |
| } else { |
| *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME; |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_DEFAULT_TLVOTA_FILE_NAME); |
| } |
| } else { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_COMPARE_FAIL); |
| } |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_COMPARE_FAIL(); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| |
| strncpy(apply_filename, MCF_FS_DEFAULT_TLVOTA_FILE_NAME, MCF_FILE_MAX_NAME_LEN - 1); |
| |
| fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt); |
| if (fs_api_ret[0] < FS_NO_ERROR) { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_TLVOTA_FILE_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_FAIL, *apply_path_type, sim_id, fs_api_ret[0]); |
| MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_FAIL(*apply_path_type, sim_id, fs_api_ret[0]); |
| dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| } else { |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| } |
| |
| if (file_size > MCF_MAX_TLVOTA_FILE_SIZE) { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_TLVOTA_FILE_OVERSIZE; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_OVERSIZE, file_size, MCF_MAX_TLVOTA_FILE_SIZE); |
| } |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_OVERSIZE(file_size, MCF_MAX_TLVOTA_FILE_SIZE); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| |
| /* Read file */ |
| fs_cmpt.opid_map = NVRAM_FS_CMPT_OPEN | NVRAM_FS_CMPT_READ | NVRAM_FS_CMPT_CLOSE; |
| fs_cmpt.Flag = FS_READ_ONLY; |
| fs_cmpt.Length = file_size; |
| fs_cmpt.Offset = 0; |
| fs_cmpt.Whence = FS_FILE_BEGIN; |
| fs_cmpt.DataPtr = tlvota_file->buff; |
| fs_cmpt.Read = &read_byte; |
| fs_cmpt.FileSize = &dummy_para; |
| |
| fs_api_ret[*apply_path_type] = FS_GetFileDetail(filename, &fs_file_detail[*apply_path_type]); |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_MODIFIED_TIME(*apply_path_type, fs_api_ret[*apply_path_type], |
| (kal_uint32)((fs_file_detail[*apply_path_type].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[*apply_path_type].LastStatusChangeTime & 0xFFFFFFFF)); |
| if (fs_api_ret[*apply_path_type] == FS_NO_ERROR) { |
| last_mod_time = fs_file_detail[*apply_path_type].LastStatusChangeTime; |
| } else { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_TLVOTA_FILE_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_FAIL, *apply_path_type, sim_id, fs_api_ret[0]); |
| MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_FAIL(*apply_path_type, sim_id, fs_api_ret[*apply_path_type]); |
| dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| |
| MCF_W_LOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| if (tlvota_file) { |
| fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt); |
| if (fs_api_ret[0] < FS_NO_ERROR) { |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_TLVOTA_FILE_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_FAIL, *apply_path_type, sim_id, fs_api_ret[0]); |
| MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_FAIL(*apply_path_type, sim_id, fs_api_ret[0]); |
| dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| |
| pFile = (mcf_tool_file_info_t *)(tlvota_file->buff); |
| #ifdef __MCF_FIND_TAG_SUPPORT__ |
| if (pFile->file_version == 2 || pFile->file_version == 3) { |
| #else |
| if (pFile->file_version == 3) { |
| #endif |
| kal_uint32 operation_mask = 0; |
| |
| /* Check custom operation mask */ |
| operation_mask = mcf_get_custom_operation_mask(); |
| if ((pFile->operation_mask & operation_mask) != operation_mask) { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_OPERATION_MASK_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_OPERATION_MASK_FAIL, apply_filename, pFile->operation_mask, operation_mask); |
| } |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_OPERATION_MASK_FAIL(apply_filename, pFile->operation_mask, operation_mask); |
| ret = MCF_OTA_R_INVALID_FILE; |
| |
| kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE); |
| kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| tlvota_file->path_type = 0; |
| tlvota_file->last_mod_time = 0; |
| kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t)); |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| |
| return ret; |
| } |
| |
| /* First check digest first |
| * If file is encrypted and has checksum. |
| * Decrypt file before checking checksum. |
| */ |
| // RSA verify digest |
| if ((pFile->operation_mask & MCF_FILE_OP_SHA256_RSA2048) != 0) { |
| |
| 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) { |
| kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE); |
| kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| tlvota_file->path_type = 0; |
| tlvota_file->last_mod_time = 0; |
| kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t)); |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DIGEST_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_DIGEST_FAIL, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_DIGEST_FAIL(apply_filename); |
| ret = MCF_OTA_R_DIGEST_FAIL; |
| |
| return ret; |
| } |
| |
| } |
| else if ((pFile->operation_mask & MCF_FILE_OP_SHA384_RSA3072) != 0) { |
| |
| 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) { |
| kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE); |
| kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| tlvota_file->path_type = 0; |
| tlvota_file->last_mod_time = 0; |
| kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t)); |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DIGEST_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_DIGEST_FAIL, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_DIGEST_FAIL(apply_filename); |
| ret = MCF_OTA_R_DIGEST_FAIL; |
| |
| return ret; |
| } |
| |
| } |
| |
| if ( (pFile->operation_mask & MCF_FILE_OP_AES_128) != 0) { |
| mcf_get_custom_aes_password(password); |
| |
| if (mcf_decrypt_128bit(password, (kal_char *)(tlvota_file->buff + pFile->total_len), (pFile->file_size - pFile->total_len) ) != KAL_TRUE) { |
| kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE); |
| kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| tlvota_file->path_type = 0; |
| tlvota_file->last_mod_time = 0; |
| kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t)); |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DECRYPTION_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_DECRYPTION_FAIL, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_DECRYPTION_FAIL(apply_filename); |
| ret = MCF_OTA_R_DECRYPTION_FAIL; |
| |
| return ret; |
| } |
| } |
| else if ((pFile->operation_mask & MCF_FILE_OP_AES_256) != 0) { // for AES_256 |
| mcf_get_custom_aes_password(password); |
| |
| if (mcf_decrypt_256bit(password, (kal_char *)(tlvota_file->buff + pFile->total_len), (pFile->file_size - pFile->total_len)) != KAL_TRUE) { |
| kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE); |
| kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| tlvota_file->path_type = 0; |
| tlvota_file->last_mod_time = 0; |
| kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t)); |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DECRYPTION_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_DECRYPTION_FAIL, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_DECRYPTION_FAIL(apply_filename); |
| ret = MCF_OTA_R_DECRYPTION_FAIL; |
| |
| return ret; |
| } |
| } |
| |
| if ( (pFile->operation_mask & MCF_FILE_OP_CHECKSUM) != 0) { |
| if (mcf_check_check_sum((kal_uint32 *)(tlvota_file->buff), pFile->file_size) != 0) { |
| kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE); |
| kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| tlvota_file->path_type = 0; |
| tlvota_file->last_mod_time = 0; |
| kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t)); |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_CHECKSUM_ERROR; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_CHECKSUM_ERROR, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_CHECKSUM_ERROR(apply_filename); |
| ret = MCF_OTA_R_CHECKSUM_ERROR; |
| |
| return ret; |
| } |
| } |
| } else { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_INVALID_FILE; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_INVALID_FILE_VERSION, pFile->file_version); |
| } |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_INVALID_FILE_VERSION(apply_filename); |
| kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE); |
| kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| tlvota_file->path_type = 0; |
| tlvota_file->last_mod_time = 0; |
| kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t)); |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| ret = MCF_OTA_R_INVALID_FILE; |
| |
| return ret; |
| } |
| |
| tlvota_file->path_type = *apply_path_type; |
| tlvota_file->last_mod_time = last_mod_time; |
| tlvota_file->last_file.last_mod_time = last_mod_time; |
| |
| #if defined(__MCF_UT_FRAMEWORK_SUPPORT__) |
| if (strcmp(tlvota_file->relative_path_name, "") == 0){ |
| strncpy(tlvota_file->relative_path_name, apply_filename, MCF_FILE_MAX_NAME_LEN - 1); |
| }else{ |
| strncpy(apply_filename, tlvota_file->relative_path_name, MCF_FILE_MAX_NAME_LEN - 1); |
| } |
| #else |
| strncpy(tlvota_file->relative_path_name, apply_filename, MCF_FILE_MAX_NAME_LEN - 1); |
| #endif |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| } else { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_TAKE_WRITE_LOCK_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_TLVOTA_FILE_TAKE_WRITE_LOCK_FAIL, apply_filename, *apply_path_type, sim_id); |
| } |
| MD_TRC_MCF_TR_READ_TLVOTA_FILE_TAKE_WRITE_LOCK_FAIL(apply_filename, *apply_path_type, sim_id); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| } |
| |
| return ret; |
| } |
| |
| mcf_ota_result_e mcf_read_general_tlvota_file( |
| kal_bool is_booting, |
| kal_char *req_fs_root_path, |
| kal_char *req_file_path_name, |
| l4c_mcf_path_type_enum *apply_path_type, |
| kal_char *apply_filename, |
| mcf_t *pMcf) |
| { |
| NVRAM_FS_PARAM_CMPT_T fs_cmpt; |
| FS_FileDetail fs_file_detail[L4C_MCF_PATH_TYPE_MAX] = {0}; |
| kal_uint32 read_byte = 0; |
| kal_uint32 file_size = 0; |
| mcf_ota_result_e ret = MCF_OTA_R_SUCCESS; |
| mcf_tlvota_file_t *tlvota_file = &(pMcf->general_tlvota_file); |
| kal_wchar filename[MCF_FILE_MAX_MD_PATH_LEN + MCF_FILE_MAX_NAME_LEN]; |
| mcf_tool_file_info_t *pFile; |
| kal_char password[MCF_MAX_PASSWORD_LEN] = {0}; |
| kal_bool is_default_path; |
| kal_uint32 dummy_para; |
| kal_int32 fs_api_ret[L4C_MCF_PATH_TYPE_MAX]; |
| kal_uint64 last_mod_time = 0; |
| mcf_tool_gid_tlvota_file_item_t *pItem; |
| kal_uint16 item_cnt = 0; |
| |
| com_Mcf.is_iccid = KAL_FALSE; |
| |
| fs_cmpt.opid_map = NVRAM_FS_CMPT_OPEN | NVRAM_FS_CMPT_GETFILESIZE | NVRAM_FS_CMPT_CLOSE; |
| fs_cmpt.Flag = FS_READ_ONLY; |
| fs_cmpt.Length = 0; |
| fs_cmpt.Offset = 0; |
| fs_cmpt.Whence = FS_FILE_BEGIN; |
| fs_cmpt.DataPtr = &dummy_para; |
| fs_cmpt.Read = &dummy_para; |
| fs_cmpt.FileSize = &file_size; |
| |
| if ( (strcmp(req_fs_root_path, "") != 0) && (strcmp(req_file_path_name, "") != 0) ) { |
| if (strcmp(req_fs_root_path, MCF_FS_DEFAULT_FOLDER_PATH) == 0) { |
| *apply_path_type = L4C_MCF_PATH_TYPE_OTA; |
| } else if (strcmp(req_fs_root_path, MCF_FS_CUSTOM_FOLDER_PATH) == 0) { |
| *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME; |
| } else{ |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_INVALID_PATH(req_fs_root_path); |
| ret = MCF_OTA_R_INVALID_PARAMETER; |
| |
| return ret; |
| } |
| kal_wsprintf(filename, "%s\\%s\0", req_fs_root_path, req_file_path_name); |
| strncpy(apply_filename, req_file_path_name, MCF_FILE_MAX_NAME_LEN - 1); |
| is_default_path = KAL_FALSE; |
| } else { |
| /* Compare modified time of general OP-OTA file to select which file to be applied */ |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_GENERAL_TLVOTA_FILE_NAME); |
| fs_api_ret[L4C_MCF_PATH_TYPE_OTA] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_OTA]); |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_OTA, fs_api_ret[L4C_MCF_PATH_TYPE_OTA], |
| (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)); |
| if (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] != FS_NO_ERROR) { |
| kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_OTA], 0, sizeof(FS_FileDetail)); |
| } |
| |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_GENERAL_TLVOTA_FILE_NAME); |
| fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME]); |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_RUNTIME, fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME], |
| (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)); |
| if (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] != FS_NO_ERROR) { |
| kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME], 0, sizeof(FS_FileDetail)); |
| } |
| |
| if ( (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] == FS_NO_ERROR) || (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] == FS_NO_ERROR) ) { |
| if (fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime > fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime) { |
| *apply_path_type = L4C_MCF_PATH_TYPE_OTA; |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_GENERAL_TLVOTA_FILE_NAME); |
| } else { |
| *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME; |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_GENERAL_TLVOTA_FILE_NAME); |
| } |
| } else { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_COMPARE_FAIL); |
| } |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_COMPARE_FAIL(); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| |
| strncpy(apply_filename, MCF_FS_GENERAL_TLVOTA_FILE_NAME, MCF_FILE_MAX_NAME_LEN - 1); |
| is_default_path = KAL_TRUE; |
| } |
| |
| fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt); |
| if (fs_api_ret[0] < FS_NO_ERROR) { |
| if (is_booting == KAL_TRUE) { |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_FAIL, *apply_path_type, fs_api_ret[0]); |
| MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_FAIL(*apply_path_type, fs_api_ret[0]); |
| dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename); |
| |
| /* If cannot read given TLV-OTA file, read default TLV-OTA file */ |
| if (is_default_path == KAL_FALSE) { |
| /* Compare modified time of general OP-OTA file to select which file to be applied */ |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_GENERAL_TLVOTA_FILE_NAME); |
| fs_api_ret[L4C_MCF_PATH_TYPE_OTA] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_OTA]); |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_OTA, fs_api_ret[L4C_MCF_PATH_TYPE_OTA], |
| (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)); |
| if (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] != FS_NO_ERROR) { |
| kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_OTA], 0, sizeof(FS_FileDetail)); |
| } |
| |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_GENERAL_TLVOTA_FILE_NAME); |
| fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] = FS_GetFileDetail(filename, &fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME]); |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_MODIFIED_TIME(L4C_MCF_PATH_TYPE_RUNTIME, fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME], |
| (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)); |
| if (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] != FS_NO_ERROR) { |
| kal_mem_set(&fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME], 0, sizeof(FS_FileDetail)); |
| } |
| |
| if ( (fs_api_ret[L4C_MCF_PATH_TYPE_OTA] == FS_NO_ERROR) || (fs_api_ret[L4C_MCF_PATH_TYPE_RUNTIME] == FS_NO_ERROR) ) { |
| if (fs_file_detail[L4C_MCF_PATH_TYPE_OTA].LastStatusChangeTime > fs_file_detail[L4C_MCF_PATH_TYPE_RUNTIME].LastStatusChangeTime) { |
| *apply_path_type = L4C_MCF_PATH_TYPE_OTA; |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, MCF_FS_GENERAL_TLVOTA_FILE_NAME); |
| } else { |
| *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME; |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, MCF_FS_GENERAL_TLVOTA_FILE_NAME); |
| } |
| } else { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_OTA_FILE_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_COMPARE_FAIL); |
| } |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_COMPARE_FAIL(); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| |
| strncpy(apply_filename, MCF_FS_GENERAL_TLVOTA_FILE_NAME, MCF_FILE_MAX_NAME_LEN - 1); |
| |
| fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt); |
| if (fs_api_ret[0] < FS_NO_ERROR) { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_TLVOTA_FILE_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_FAIL, *apply_path_type, fs_api_ret[0]); |
| MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_FAIL(*apply_path_type, fs_api_ret[0]); |
| dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| } else { |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| } |
| |
| if (file_size > MCF_MAX_TLVOTA_FILE_SIZE) { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_TLVOTA_FILE_OVERSIZE; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_OVERSIZE, file_size, MCF_MAX_TLVOTA_FILE_SIZE); |
| } |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_OVERSIZE(file_size, MCF_MAX_TLVOTA_FILE_SIZE); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| |
| /* Read file */ |
| fs_cmpt.opid_map = NVRAM_FS_CMPT_OPEN | NVRAM_FS_CMPT_READ | NVRAM_FS_CMPT_CLOSE; |
| fs_cmpt.Flag = FS_READ_ONLY; |
| fs_cmpt.Length = file_size; |
| fs_cmpt.Offset = 0; |
| fs_cmpt.Whence = FS_FILE_BEGIN; |
| fs_cmpt.DataPtr = tlvota_file->buff; |
| fs_cmpt.Read = &read_byte; |
| fs_cmpt.FileSize = &dummy_para; |
| |
| fs_api_ret[*apply_path_type] = FS_GetFileDetail(filename, &fs_file_detail[*apply_path_type]); |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_MODIFIED_TIME(*apply_path_type, fs_api_ret[*apply_path_type], |
| (kal_uint32)((fs_file_detail[*apply_path_type].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[*apply_path_type].LastStatusChangeTime & 0xFFFFFFFF)); |
| if (fs_api_ret[*apply_path_type] == FS_NO_ERROR) { |
| last_mod_time = fs_file_detail[*apply_path_type].LastStatusChangeTime; |
| } else { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_TLVOTA_FILE_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_FAIL, *apply_path_type, fs_api_ret[0]); |
| MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_FAIL(*apply_path_type, fs_api_ret[*apply_path_type]); |
| dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| |
| MCF_W_LOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| if (tlvota_file) { |
| fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt); |
| if (fs_api_ret[0] < FS_NO_ERROR) { |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_READ_TLVOTA_FILE_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_FAIL, *apply_path_type, fs_api_ret[0]); |
| MCF_BOOT_TRACE(MCF_BOOT_TR_STRING, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_FAIL(*apply_path_type, fs_api_ret[0]); |
| dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| |
| return ret; |
| } |
| |
| com_Mcf.is_iccid = KAL_FALSE; |
| pFile = (mcf_tool_file_info_t *)(tlvota_file->buff); |
| #ifdef __MCF_FIND_TAG_SUPPORT__ |
| if (pFile->file_version == 2 || pFile->file_version == 3) { |
| #else |
| if (pFile->file_version == 3) { |
| #endif |
| kal_uint32 operation_mask = 0; |
| |
| /* Check custom operation mask */ |
| operation_mask = mcf_get_custom_operation_mask(); |
| if ((pFile->operation_mask & operation_mask) != operation_mask) { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_OPERATION_MASK_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_OPERATION_MASK_FAIL, apply_filename, pFile->operation_mask, operation_mask); |
| } |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_OPERATION_MASK_FAIL(apply_filename, pFile->operation_mask, operation_mask); |
| ret = MCF_OTA_R_INVALID_FILE; |
| |
| kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE); |
| kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| tlvota_file->path_type = 0; |
| tlvota_file->last_mod_time = 0; |
| kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t)); |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| |
| return ret; |
| } |
| /* First check digest first |
| * If file is encrypted and has checksum. |
| * Decrypt file before checking checksum. |
| */ |
| // RSA verify digest |
| if ((pFile->operation_mask & MCF_FILE_OP_SHA256_RSA2048) != 0) { |
| |
| 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) { |
| kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE ); |
| kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| tlvota_file->path_type = 0; |
| tlvota_file->last_mod_time = 0; |
| kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t)); |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DIGEST_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_DIGEST_FAIL, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_DIGEST_FAIL(apply_filename); |
| ret = MCF_OTA_R_DIGEST_FAIL; |
| |
| return ret; |
| } |
| |
| } |
| |
| else if ((pFile->operation_mask & MCF_FILE_OP_SHA384_RSA3072) != 0) { |
| |
| 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) { |
| kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE ); |
| kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| tlvota_file->path_type = 0; |
| tlvota_file->last_mod_time = 0; |
| kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t)); |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DIGEST_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_DIGEST_FAIL, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_DIGEST_FAIL(apply_filename); |
| ret = MCF_OTA_R_DIGEST_FAIL; |
| |
| return ret; |
| } |
| |
| } |
| |
| if ( (pFile->operation_mask & MCF_FILE_OP_AES_128) != 0) { |
| mcf_get_custom_aes_password(password); |
| |
| if (mcf_decrypt_128bit(password, (kal_char *)(tlvota_file->buff + pFile->total_len), (pFile->file_size - pFile->total_len) ) != KAL_TRUE) { |
| kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE ); |
| kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| tlvota_file->path_type = 0; |
| tlvota_file->last_mod_time = 0; |
| kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t)); |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DECRYPTION_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_DECRYPTION_FAIL, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_DECRYPTION_FAIL(apply_filename); |
| ret = MCF_OTA_R_DECRYPTION_FAIL; |
| |
| return ret; |
| } |
| } |
| else if ((pFile->operation_mask & MCF_FILE_OP_AES_256) != 0) { // for AES_256 |
| mcf_get_custom_aes_password(password); |
| |
| if (mcf_decrypt_256bit(password, (kal_char *)(tlvota_file->buff + pFile->total_len), (pFile->file_size - pFile->total_len)) != KAL_TRUE) { |
| kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE); |
| kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| tlvota_file->path_type = 0; |
| tlvota_file->last_mod_time = 0; |
| kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t)); |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_DECRYPTION_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_DECRYPTION_FAIL, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_DECRYPTION_FAIL(apply_filename); |
| ret = MCF_OTA_R_DECRYPTION_FAIL; |
| |
| return ret; |
| } |
| } |
| |
| if ( (pFile->operation_mask & MCF_FILE_OP_CHECKSUM) != 0) { |
| if (mcf_check_check_sum((kal_uint32 *)(tlvota_file->buff), pFile->file_size) != 0) { |
| kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE); |
| kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| tlvota_file->path_type = 0; |
| tlvota_file->last_mod_time = 0; |
| kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t)); |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_CHECKSUM_ERROR; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_CHECKSUM_ERROR, apply_filename); |
| } |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_CHECKSUM_ERROR(apply_filename); |
| ret = MCF_OTA_R_CHECKSUM_ERROR; |
| |
| return ret; |
| } |
| } |
| |
| //Check whether general TLV-OTA have iccid tag |
| pItem = (mcf_tool_gid_tlvota_file_item_t *)(tlvota_file->buff + pFile->total_len); |
| while (item_cnt < pFile->item_num) { |
| if ((pItem->tag_type == MCF_TLVOTA_TAG_ICCID)) { |
| com_Mcf.is_iccid = KAL_TRUE; |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_TAG_TYPE(MCF_TLVOTA_TAG_ICCID); |
| break; |
| } |
| pItem = (mcf_tool_gid_tlvota_file_item_t *)((kal_uint8 *)pItem + pItem->total_len); |
| item_cnt++; |
| } |
| } else { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_INVALID_FILE; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_INVALID_FILE_VERSION, pFile->file_version); |
| } |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_INVALID_FILE_VERSION(pFile->file_version); |
| kal_mem_set(tlvota_file->buff, 0, MCF_MAX_TLVOTA_FILE_SIZE); |
| kal_mem_set(tlvota_file->relative_path_name, 0, MCF_FILE_MAX_NAME_LEN); |
| tlvota_file->path_type = 0; |
| tlvota_file->last_mod_time = 0; |
| kal_mem_set(&(tlvota_file->last_file), 0, sizeof(mcf_file_info_t)); |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| ret = MCF_OTA_R_INVALID_FILE; |
| |
| return ret; |
| } |
| |
| tlvota_file->path_type = *apply_path_type; |
| #if defined(__MCF_UT_FRAMEWORK_SUPPORT__) |
| if (strcmp(tlvota_file->relative_path_name, "") == 0){ |
| strncpy(tlvota_file->relative_path_name, apply_filename, MCF_FILE_MAX_NAME_LEN - 1); |
| }else{ |
| strncpy(apply_filename, tlvota_file->relative_path_name, MCF_FILE_MAX_NAME_LEN - 1); |
| } |
| #else |
| strncpy(tlvota_file->relative_path_name, apply_filename, MCF_FILE_MAX_NAME_LEN - 1); |
| #endif |
| tlvota_file->last_mod_time = last_mod_time; |
| tlvota_file->last_file.last_mod_time = last_mod_time; |
| MCF_W_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| } else { |
| if (is_booting == KAL_TRUE) { |
| com_Mcf.boot_trace_flag |= MCF_BOOT_TRACE_F_TAKE_WRITE_LOCK_FAIL; |
| MCF_BOOT_TRACE(MCF_BOOT_TR_READ_GENERAL_TLVOTA_FILE_TAKE_WRITE_LOCK_FAIL, apply_filename, *apply_path_type); |
| } |
| MD_TRC_MCF_TR_READ_GENERAL_TLVOTA_FILE_TAKE_WRITE_LOCK_FAIL(apply_filename, *apply_path_type); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| } |
| |
| |
| return ret; |
| } |
| |
| mcf_ota_result_e mcf_read_ini_file( |
| kal_char *req_fs_root_path, |
| kal_char *req_file_path_name, |
| l4c_mcf_path_type_enum *apply_path_type, |
| kal_char *apply_filename, |
| mcf_t *pMcf) |
| { |
| NVRAM_FS_PARAM_CMPT_T fs_cmpt; |
| kal_uint32 read_byte = 0; |
| kal_uint32 file_size = 0; |
| mcf_ota_result_e ret = MCF_OTA_R_SUCCESS; |
| mcf_ini_file_t *ini_file = &(pMcf->ini_file); |
| kal_wchar filename[MCF_FILE_MAX_MD_PATH_LEN + MCF_FILE_MAX_NAME_LEN]; |
| kal_bool is_default_path; |
| kal_uint32 dummy_para; |
| kal_int32 fs_api_ret[L4C_MCF_PATH_TYPE_MAX]; |
| |
| fs_cmpt.opid_map = NVRAM_FS_CMPT_OPEN | NVRAM_FS_CMPT_GETFILESIZE | NVRAM_FS_CMPT_CLOSE; |
| fs_cmpt.Flag = FS_READ_ONLY; |
| fs_cmpt.Length = 0; |
| fs_cmpt.Offset = 0; |
| fs_cmpt.Whence = FS_FILE_BEGIN; |
| fs_cmpt.DataPtr = &dummy_para; |
| fs_cmpt.Read = &dummy_para; |
| fs_cmpt.FileSize = &file_size; |
| |
| |
| if ( (strcmp(req_fs_root_path, "") != 0) && (strcmp(req_file_path_name, "") != 0) ) { |
| if (strcmp(req_fs_root_path, MCF_FS_DEFAULT_FOLDER_PATH) == 0) { |
| *apply_path_type = L4C_MCF_PATH_TYPE_OTA; |
| } else if (strcmp(req_fs_root_path, MCF_FS_CUSTOM_FOLDER_PATH) == 0) { |
| *apply_path_type = L4C_MCF_PATH_TYPE_RUNTIME; |
| } |
| kal_wsprintf(filename, "%s\\%s\0", req_fs_root_path, req_file_path_name); |
| strncpy(apply_filename, req_file_path_name, MCF_FILE_MAX_NAME_LEN - 1); |
| is_default_path = KAL_FALSE; |
| } else { |
| if (*apply_path_type == L4C_MCF_PATH_TYPE_OTA) { |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, apply_filename); |
| } else if (*apply_path_type == L4C_MCF_PATH_TYPE_RUNTIME) { |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, apply_filename); |
| } |
| strncpy(apply_filename, MCF_FS_DEFAULT_INI_FILE_NAME, MCF_FILE_MAX_NAME_LEN - 1); |
| is_default_path = KAL_TRUE; |
| } |
| |
| fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt); |
| if (fs_api_ret[0] < FS_NO_ERROR) { |
| |
| MD_TRC_MCF_TR_READ_INI_FILE_FAIL(*apply_path_type, fs_api_ret[0]); |
| dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename); |
| |
| /* If cannot read given INI file, read default INI file */ |
| if (is_default_path == KAL_FALSE) { |
| if (*apply_path_type == L4C_MCF_PATH_TYPE_OTA) { |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, apply_filename); |
| } else if (*apply_path_type == L4C_MCF_PATH_TYPE_RUNTIME) { |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, apply_filename); |
| } |
| strncpy(apply_filename, MCF_FS_DEFAULT_INI_FILE_NAME, MCF_FILE_MAX_NAME_LEN - 1); |
| |
| fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt); |
| if (fs_api_ret[0] < FS_NO_ERROR) { |
| |
| MD_TRC_MCF_TR_READ_INI_FILE_FAIL(*apply_path_type, fs_api_ret[0]); |
| dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename); |
| ret = MCF_OTA_R_READ_INI_FILE_FAIL; |
| |
| return ret; |
| } |
| } else { |
| ret = MCF_OTA_R_READ_INI_FILE_FAIL; |
| |
| return ret; |
| } |
| } |
| if (file_size >= MCF_MAX_INI_FILE_SIZE-1) { |
| MD_TRC_MCF_TR_READ_INI_FILE_OVERSIZE(file_size, MCF_MAX_INI_FILE_SIZE); |
| ret = MCF_OTA_R_READ_INI_FILE_FAIL; |
| |
| return ret; |
| } |
| |
| /* Read file */ |
| fs_cmpt.opid_map = NVRAM_FS_CMPT_OPEN | NVRAM_FS_CMPT_READ | NVRAM_FS_CMPT_CLOSE; |
| fs_cmpt.Flag = FS_READ_ONLY; |
| fs_cmpt.Length = file_size; |
| fs_cmpt.Offset = 0; |
| fs_cmpt.Whence = FS_FILE_BEGIN; |
| fs_cmpt.DataPtr = ini_file->buff; |
| fs_cmpt.Read = &read_byte; |
| fs_cmpt.FileSize = &dummy_para; |
| |
| |
| fs_api_ret[0] = MCF_FS_CMPT_Read(filename, &fs_cmpt); |
| if (fs_api_ret[0] < FS_NO_ERROR) { |
| MD_TRC_MCF_TR_READ_INI_FILE_FAIL(*apply_path_type, fs_api_ret[0]); |
| dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, apply_filename); |
| ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| return ret; |
| } |
| |
| if (file_size < MCF_MAX_INI_FILE_SIZE){ |
| ini_file->buff[file_size] = '\0'; |
| } |
| |
| |
| return ret; |
| } |
| |
| kal_bool mcf_find_ini_item(kal_char* buff, kal_char *item, kal_char *value, mcf_t *pMcf) |
| { |
| kal_bool ret = KAL_TRUE; |
| kal_char *varstr = NULL, *substr = NULL; |
| kal_char *saveptr = NULL; |
| kal_char *item_ptr = NULL; |
| kal_char *item_tag = NULL; |
| mcf_ini_file_t *ini_file = &(pMcf->ini_file); |
| kal_char *buffer = (kal_char *)ini_file->tmp_buff; |
| |
| |
| |
| //buff and item cannot be NULL |
| if(buff == NULL || item == NULL) { |
| MD_TRC_MCF_TR_FIND_INI_ITEM_ERROR_INPUT_NULL(); |
| ret = KAL_FALSE; |
| return ret; |
| } |
| |
| MD_TRC_MCF_TR_FIND_INI_ITEM_START(item); |
| |
| /* Remove space and to uppercase */ |
| mcf_remove_spaces_and_carrier_return(buff); |
| mcf_toupper(buff); |
| mcf_toupper(item); |
| mcf_remove_spaces_and_carrier_return(item); |
| |
| kal_mem_set(buffer,0,MCF_MAX_INI_FILE_SIZE); |
| strncpy(buffer,buff,MCF_MAX_INI_FILE_SIZE-1); |
| buffer[MCF_MAX_INI_FILE_SIZE-1] = '\0'; |
| |
| |
| item_ptr = strstr (buffer,item); |
| if (item_ptr != 0) { |
| item_tag = kal_strtok_r(item_ptr,"=",&saveptr); |
| substr = kal_strtok_r(NULL,"=",&saveptr); |
| if (item_tag != 0) { |
| if (strcmp(item_tag,item) == 0){ |
| if (substr != NULL){ |
| varstr = strstr(substr,"\n"); |
| if (varstr == NULL){ |
| if (strlen(substr) > MCF_MAX_INI_ITEM_VALUE_LEN-1){ |
| memset(value, 0, MCF_MAX_INI_ITEM_VALUE_LEN); |
| strncpy(value, substr, MCF_MAX_INI_ITEM_VALUE_LEN); |
| }else{ |
| memset(value, 0, MCF_MAX_INI_ITEM_VALUE_LEN); |
| strncpy(value, substr, strlen(substr)); |
| } |
| |
| }else{ |
| if (strlen(substr)-strlen(varstr) + 1 > MCF_MAX_INI_ITEM_VALUE_LEN-1){ |
| memset(value, 0, MCF_MAX_INI_ITEM_VALUE_LEN); |
| strncpy(value, substr, MCF_MAX_INI_ITEM_VALUE_LEN); |
| }else{ |
| memset(value, 0, MCF_MAX_INI_ITEM_VALUE_LEN); |
| strncpy(value, substr, strlen(substr)-strlen(varstr)); |
| } |
| |
| |
| } |
| }else{ |
| value = NULL; |
| MD_TRC_MCF_TR_FIND_INI_ITEM_ERROR_CAN_NOT_FIND_ITEM(); |
| ret = KAL_FALSE; |
| return ret; |
| } |
| }else{ |
| value = NULL; |
| MD_TRC_MCF_TR_FIND_INI_ITEM_ERROR_ITEM_LENGTH(); |
| ret = KAL_FALSE; |
| return ret; |
| } |
| |
| } else { |
| value = NULL; |
| MD_TRC_MCF_TR_FIND_INI_ITEM_ERROR_CAN_NOT_FIND_ITEM(); |
| ret = KAL_FALSE; |
| return ret; |
| } |
| } else { |
| value = NULL; |
| MD_TRC_MCF_TR_FIND_INI_ITEM_ERROR_CAN_NOT_FIND_ITEM(); |
| ret = KAL_FALSE; |
| return ret; |
| } |
| |
| |
| |
| MD_TRC_MCF_TR_FIND_INI_ITEM_RETURN_VALUE(item, value); |
| |
| return ret; |
| } |
| |
| kal_bool mcf_find_ini_sbp_id(kal_char *tag_str, kal_uint32 *sbp_id, kal_uint16 *sbp_id_num, kal_bool *general) |
| { |
| kal_uint16 i = 0; |
| kal_bool ret = KAL_TRUE; |
| kal_char *saveptr = NULL, *varstr = NULL, *substr = NULL, *tmpstr = NULL; |
| kal_char *sbp_id_tag[MCF_MAX_TAG_NUM]; |
| kal_uint16 tag_cnt = 0; |
| kal_char *tag[MCF_MAX_TAG_NUM]; |
| kal_uint16 tag_num = 0; |
| |
| MD_TRC_MCF_TR_FIND_INI_SBP_ID_START(tag_str); |
| |
| //buff and item cannot be NULL |
| if(tag_str == NULL) { |
| MD_TRC_MCF_TR_FIND_INI_SBP_ID_ERROR_INPUT_NULL(); |
| ret = KAL_FALSE; |
| return ret; |
| } |
| |
| |
| //Split ',' from tag |
| substr = kal_strtok_r(tag_str, ",", &saveptr); |
| |
| if (substr == NULL){ |
| MD_TRC_MCF_TR_FIND_INI_SBP_ID_ERROR_CAN_NOT_FIND_ITEM(); |
| ret = KAL_FALSE; |
| return ret; |
| } |
| |
| |
| while(substr != NULL){ |
| tag[tag_cnt] = substr; |
| tag_cnt++; |
| substr = kal_strtok_r(NULL, ",",&saveptr); |
| } |
| |
| |
| |
| /* ICCID case should apply general tlvota*/ |
| tmpstr = strstr(tag[0], "_"); |
| if (tmpstr == NULL){ |
| *general = KAL_TRUE; |
| MD_TRC_MCF_TR_FIND_INI_SBP_ID_ICCID_USIR(tag[0]); |
| } |
| |
| //Split '_' from SBPID_MNC_MCC tag |
| sbp_id_tag[0] = kal_strtok_r(tag[0], "_", &saveptr); |
| |
| if (strcmp(sbp_id_tag[0],"") == 0){ |
| MD_TRC_MCF_TR_FIND_INI_SBP_ID_ERROR_CAN_NOT_FIND_ITEM(); |
| } |
| |
| |
| /* NA case should apply general tlvota */ |
| if (strcmp(sbp_id_tag[0],"NA") == 0){ |
| *general = KAL_TRUE; |
| MD_TRC_MCF_TR_FIND_INI_SBP_ID_NA(*general); |
| } |
| |
| for (i = 1; i < tag_cnt; i++){ |
| |
| tmpstr = strstr(tag[i], "_"); |
| if (tmpstr == NULL){ |
| *general = KAL_TRUE; |
| if(i+1 < tag_cnt){ |
| i++; |
| } |
| }else{ |
| varstr = kal_strtok_r(tag[i], "_",&saveptr); |
| if(varstr == NULL){ |
| *general = KAL_TRUE; |
| if(i+1 < tag_cnt){ |
| i++; |
| } |
| }else{ |
| if(strcmp(varstr,"NA") == 0){ |
| *general = KAL_TRUE; |
| if(i+1 < tag_cnt){ |
| i++; |
| } |
| } |
| if (strcmp(varstr,sbp_id_tag[tag_num]) != 0){ |
| //save different sbp_id |
| tag_num++; |
| sbp_id_tag[tag_num] = varstr; |
| } |
| } |
| } |
| } |
| |
| for (i = 0; i < tag_num + 1; i++){ |
| sbp_id[i] = mcf_atoi(sbp_id_tag[i]); |
| } |
| |
| |
| |
| *sbp_id_num = tag_num + 1; |
| |
| MD_TRC_MCF_TR_FIND_INI_SBP_ID_RETURN_NUM(*sbp_id_num); |
| |
| return ret; |
| } |
| |
| kal_bool mcf_compose_ini_item(kal_char *orig_buff, kal_char *new_buff, kal_char *item, kal_char *orig_value, kal_char *value) |
| { |
| kal_bool ret = KAL_TRUE; |
| kal_char *tmpstr = NULL, *varstr = NULL, *substr = NULL; |
| kal_uint32 len = 0; |
| |
| MD_TRC_MCF_TR_COMPOSE_INI_ITEM_START(item, orig_value); |
| |
| mcf_remove_spaces_and_carrier_return(orig_buff); |
| mcf_remove_spaces_and_carrier_return(item); |
| kal_mem_set(new_buff, 0, MCF_MAX_INI_FILE_SIZE); |
| |
| substr = strstr (orig_buff,"\0"); |
| if (substr != NULL){ |
| len = strlen(orig_buff); |
| }else{ |
| MD_TRC_MCF_TR_COMPOSE_INI_ITEM_INVALID_BUFF(); |
| ret = KAL_FALSE; |
| return ret; |
| } |
| |
| |
| |
| substr = strstr (orig_buff,item); |
| if (substr != NULL){ |
| varstr = strstr(substr,"="); |
| if (varstr != NULL){ |
| if (strlen(substr)-strlen(varstr) == strlen(item)){ |
| if(strcmp(orig_value,"") != 0){ |
| tmpstr = strstr(substr,orig_value); |
| if (tmpstr != NULL){ |
| if ((len-strlen(varstr)+4+strlen(value)+strlen(tmpstr)-strlen(orig_value)) >= MCF_MAX_INI_FILE_SIZE){ |
| MD_TRC_MCF_TR_COMPOSE_INI_ITEM_INVALID_BUFF_LENGTH(); |
| ret = KAL_FALSE; |
| return ret; |
| } |
| strncpy(new_buff,orig_buff,len-strlen(varstr)); |
| strncat (new_buff,"=", MCF_MAX_INI_FILE_SIZE - 1); |
| strncat (new_buff,value, MCF_MAX_INI_FILE_SIZE - 1); |
| strncat (new_buff,tmpstr+strlen(orig_value), MCF_MAX_INI_FILE_SIZE - 1); |
| strncat (new_buff,"\n\0", MCF_MAX_INI_FILE_SIZE - 1); |
| }else{ |
| MD_TRC_MCF_TR_COMPOSE_INI_ITEM_INVALID_ORIGINAL_VALUE(orig_value); |
| ret = KAL_FALSE; |
| return ret; |
| } |
| }else{ |
| if ((len-strlen(varstr)+4+strlen(value)+strlen(substr)-strlen(item)) >= MCF_MAX_INI_FILE_SIZE){ |
| MD_TRC_MCF_TR_COMPOSE_INI_ITEM_INVALID_BUFF_LENGTH(); |
| ret = KAL_FALSE; |
| return ret; |
| } |
| strncpy(new_buff,orig_buff,len-strlen(varstr)); |
| strncat (new_buff,"=", MCF_MAX_INI_FILE_SIZE - 1); |
| strncat (new_buff,value, MCF_MAX_INI_FILE_SIZE - 1); |
| strncat (new_buff,"\n", MCF_MAX_INI_FILE_SIZE - 1); |
| strncat (new_buff,substr+strlen(item)+1, MCF_MAX_INI_FILE_SIZE - 1); |
| strncat (new_buff,"\n\0", MCF_MAX_INI_FILE_SIZE - 1); |
| } |
| }else{ |
| MD_TRC_MCF_TR_COMPOSE_INI_ITEM_ERROR_ITEM_LENGTH(); |
| ret = KAL_FALSE; |
| return ret; |
| |
| } |
| }else{ |
| tmpstr = strstr(substr,orig_value); |
| if (tmpstr != NULL){ |
| if ((len+4+strlen(value)+strlen(tmpstr)-strlen(orig_value)) >= MCF_MAX_INI_FILE_SIZE){ |
| MD_TRC_MCF_TR_COMPOSE_INI_ITEM_INVALID_BUFF_LENGTH(); |
| ret = KAL_FALSE; |
| return ret; |
| } |
| strncpy(new_buff,orig_buff,len); |
| strncat (new_buff,"=", MCF_MAX_INI_FILE_SIZE - 1); |
| strncat (new_buff,value, MCF_MAX_INI_FILE_SIZE - 1); |
| strncat (new_buff,tmpstr+strlen(orig_value), MCF_MAX_INI_FILE_SIZE - 1); |
| strncat (new_buff,"\n\0", MCF_MAX_INI_FILE_SIZE - 1); |
| }else{ |
| MD_TRC_MCF_TR_COMPOSE_INI_ITEM_INVALID_ORIGINAL_VALUE(orig_value); |
| ret = KAL_FALSE; |
| return ret; |
| } |
| } |
| |
| |
| } |
| else{ |
| //new item |
| if ((len+5+strlen(item)+strlen(value)) >= MCF_MAX_INI_FILE_SIZE){ |
| MD_TRC_MCF_TR_COMPOSE_INI_ITEM_INVALID_BUFF_LENGTH(); |
| ret = KAL_FALSE; |
| return ret; |
| } |
| strncpy(new_buff,orig_buff, MCF_MAX_INI_FILE_SIZE - 1); |
| strncat(new_buff,"\n", MCF_MAX_INI_FILE_SIZE - 1); |
| strncat(new_buff,item, MCF_MAX_INI_FILE_SIZE - 1); |
| strncat(new_buff,"=", MCF_MAX_INI_FILE_SIZE - 1); |
| strncat(new_buff,value, MCF_MAX_INI_FILE_SIZE - 1); |
| strncat (new_buff,"\n\0", MCF_MAX_INI_FILE_SIZE - 1); |
| } |
| |
| |
| return ret; |
| } |
| |
| void mcf_dump_data(kal_bool is_booting, void *p_data, kal_uint32 len) |
| { |
| kal_uint32 i = 0; |
| kal_uint32 buff; |
| |
| for (i = 0; len > 0; i++){ |
| if (len >= 4) { |
| buff = 0; |
| kal_mem_cpy(&buff, (kal_uint8 *)p_data + (i * 4), 4); |
| len -= 4; |
| } else { |
| buff = 0; |
| kal_mem_cpy(&buff, (kal_uint8 *)p_data + (i * 4), len); |
| len = 0; |
| } |
| |
| if (is_booting == KAL_TRUE) { |
| MCF_BOOT_TRACE(MCF_BOOT_TR_DATA_DUMP_TRACE, i, buff); |
| } |
| MD_TRC_MCF_TR_DATA_DUMP_TRACE(i, buff); |
| } |
| } |
| |
| #define GUARD_PARRTEN 0xAABBCCDD |
| #define FULL_PARRTEN 0xAABBFFFF |
| void mcf_write_boot_trace(kal_uint32 trace_enum, ...) |
| { |
| va_list ap; |
| kal_uint32 i = 0; |
| kal_uint32 *value= NULL; |
| char *substr = NULL; |
| // store into com_Mcf.boot_trace_buff |
| // enum, num, type, size, value, type, size, value |
| // enum, num, type, size, value, type, size, value |
| // enum, num, type, size, value, type, size, value |
| mcf_boot_trace_struct *trace_ptr = (mcf_boot_trace_struct *)com_Mcf.boot_trace_buff_ptr; |
| mcf_boot_trace_value_struct *value_ptr = NULL; |
| |
| if(com_Mcf.boot_trace_buff_ptr == NULL ){ |
| com_Mcf.boot_trace_buff_ptr = (kal_uint32 *)com_Mcf.boot_trace_buff; |
| trace_ptr = (mcf_boot_trace_struct *)com_Mcf.boot_trace_buff_ptr; |
| } |
| |
| value_ptr = &trace_ptr->value_ptr; |
| |
| if((char *)trace_ptr + 512 > (char *)com_Mcf.boot_trace_buff + sizeof(com_Mcf.boot_trace_buff)) |
| { |
| if(com_Mcf.boot_trace_full == 1) return; |
| com_Mcf.boot_trace_full = 1; |
| trace_ptr->guard_pattern = GUARD_PARRTEN; |
| trace_ptr->trace_enum = FULL_PARRTEN; |
| com_Mcf.boot_trace_buff_ptr = (kal_uint32 *)(trace_ptr+1); |
| return; |
| } |
| |
| trace_ptr->guard_pattern = GUARD_PARRTEN; |
| trace_ptr->trace_enum = trace_enum; |
| |
| substr = strstr(boot_trace_format[trace_enum].log_format, "%"); |
| va_start(ap, trace_enum); |
| while ( (kal_uint32)(value = (kal_uint32 *)va_arg(ap,void *)) != END_PATTERN) |
| { |
| if(substr == NULL) break; |
| |
| switch(*(substr + 1)) |
| { |
| case 's': |
| { |
| char *string_ptr = (char *)value; |
| value_ptr->size = strlen(string_ptr); |
| kal_mem_cpy(&value_ptr->type_u.string, string_ptr, value_ptr->size + 1); |
| value_ptr->size = ((value_ptr->size + 4) >> 2 ) << 2 ; // size pedding to 4 byte alignment |
| value_ptr->type = MCF_TYPE_STRING; |
| } |
| break; |
| default: |
| { |
| value_ptr->size = sizeof(kal_uint32); |
| value_ptr->type_u.integer = (kal_uint32)value; |
| value_ptr->type = MCF_TYPE_INTEGER; |
| } |
| break; |
| } |
| |
| i++; |
| value_ptr = (mcf_boot_trace_value_struct *)((kal_uint8 *)&value_ptr->type_u.value + value_ptr->size); |
| |
| substr = strstr(substr + 1, "%"); |
| } |
| va_end(ap); |
| |
| trace_ptr->total_num = i; |
| |
| if(trace_ptr->total_num == 0 ) com_Mcf.boot_trace_buff_ptr = (kal_uint32 *)(trace_ptr+1); |
| else com_Mcf.boot_trace_buff_ptr = (kal_uint32 *)value_ptr; |
| } |
| |
| void mcf_dump_boot_trace(void) |
| { |
| mcf_boot_trace_struct *trace_ptr = (mcf_boot_trace_struct *)com_Mcf.boot_trace_buff; |
| kal_uint32 i = 0; |
| mcf_boot_trace_value_struct value_list[7]; // max DHL arg is 7 |
| mcf_boot_trace_value_struct *current_value; |
| |
| while ((char *)trace_ptr < (char *)com_Mcf.boot_trace_buff_ptr) |
| { |
| ASSERT(trace_ptr->guard_pattern == GUARD_PARRTEN); |
| current_value = &trace_ptr->value_ptr; |
| |
| if(trace_ptr->trace_enum == FULL_PARRTEN) |
| { |
| MCF_BOOT_PRINT("[MCF] boot trace buffer full!!!"); |
| break; |
| } |
| |
| for(i = 0 ; i < trace_ptr->total_num ; i++) |
| { |
| value_list[i].size = current_value->size; |
| switch(current_value->type) |
| { |
| case MCF_TYPE_INTEGER: |
| value_list[i].type_u.value = current_value->type_u.integer; |
| break; |
| case MCF_TYPE_STRING: |
| value_list[i].type_u.value = (kal_uint32)¤t_value->type_u.string; |
| break; |
| default: |
| break; |
| } |
| current_value = (mcf_boot_trace_value_struct *)((kal_uint8 *)¤t_value->type_u.value + current_value->size); |
| } |
| switch(trace_ptr->total_num) |
| { |
| case 0: |
| MCF_BOOT_PRINT(boot_trace_format[trace_ptr->trace_enum].log_format); |
| break; |
| case 1: |
| MCF_BOOT_PRINT(boot_trace_format[trace_ptr->trace_enum].log_format, value_list[0].type_u.value); |
| break; |
| case 2: |
| MCF_BOOT_PRINT(boot_trace_format[trace_ptr->trace_enum].log_format, value_list[0].type_u.value, value_list[1].type_u.value); |
| break; |
| case 3: |
| 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); |
| break; |
| case 4: |
| 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); |
| break; |
| case 5: |
| 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); |
| break; |
| case 6: |
| 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); |
| break; |
| case 7: |
| 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); |
| break; |
| } |
| |
| if(trace_ptr->total_num == 0) trace_ptr++; |
| else trace_ptr = (mcf_boot_trace_struct *)current_value; |
| } |
| } |
| |
| mcf_ota_result_e mcf_write_buffer( |
| kal_char *folder_path, |
| kal_char *file_name, |
| kal_uint8 *buffer, |
| kal_uint32 total_size) |
| { |
| mcf_ota_result_e mcf_ret = MCF_OTA_R_SUCCESS; |
| #if defined(__MTK_TARGET__) |
| kal_wchar file_path_name[MCF_FILE_MAX_MD_PATH_LEN * 2]; |
| FS_HANDLE file_handle; |
| kal_uint32 len = 0; |
| kal_int32 ret = FS_NO_ERROR; |
| |
| MD_TRC_MCF_TR_WRITE_BUFFER_START(file_name, folder_path, total_size); |
| |
| kal_wsprintf(file_path_name, "%s\\%s\0", folder_path, file_name); |
| file_handle = FS_Open(file_path_name, FS_CREATE | FS_READ_WRITE | FS_OPEN_NO_DIR); |
| |
| ret = FS_Write(file_handle, buffer, total_size, &len); |
| if (ret != FS_NO_ERROR) { |
| MD_TRC_MCF_TR_WRITE_BUFFER_FAIL(file_handle, ret); |
| mcf_ret = MCF_OTA_R_WRITE_DISK_FAIL; |
| } |
| |
| FS_Close(file_handle); |
| #endif |
| return mcf_ret; |
| } |
| |
| mcf_ota_result_e mcf_get_file_last_mod_time( |
| kal_char *apply_filename, |
| l4c_mcf_path_type_enum apply_path_type, |
| kal_uint64 *last_mod_time) |
| { |
| mcf_ota_result_e mcf_ret = MCF_OTA_R_SUCCESS; |
| kal_wchar filename[MCF_FILE_MAX_MD_PATH_LEN + MCF_FILE_MAX_NAME_LEN]; |
| FS_FileDetail fs_file_detail[L4C_MCF_PATH_TYPE_MAX] = {0}; |
| kal_int32 fs_api_ret[L4C_MCF_PATH_TYPE_MAX]; |
| |
| MD_TRC_MCF_TR_GET_FILE_LAST_MOD_TIME_START(apply_filename, apply_path_type); |
| if (apply_path_type == L4C_MCF_PATH_TYPE_OTA){ |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_DEFAULT_FOLDER_PATH, apply_filename); |
| }else if(apply_path_type == L4C_MCF_PATH_TYPE_RUNTIME){ |
| kal_wsprintf(filename, "%s\\%s\0", MCF_FS_CUSTOM_FOLDER_PATH, apply_filename); |
| }else{ |
| *last_mod_time = 0; |
| MD_TRC_MCF_TR_GET_FILE_LAST_MOD_TIME_INVALID_PATH_TYPE(apply_path_type); |
| mcf_ret = MCF_OTA_R_INVALID_PARAMETER; |
| return mcf_ret; |
| } |
| fs_api_ret[apply_path_type] = FS_GetFileDetail(filename, &fs_file_detail[apply_path_type]); |
| MD_TRC_MCF_TR_GET_FILE_LAST_MOD_TIME(apply_path_type, fs_api_ret[apply_path_type], |
| (kal_uint32)((fs_file_detail[apply_path_type].LastStatusChangeTime >> 32) & 0xFFFFFFFF), (kal_uint32)(fs_file_detail[apply_path_type].LastStatusChangeTime & 0xFFFFFFFF)); |
| if (fs_api_ret[apply_path_type] == FS_NO_ERROR) { |
| *last_mod_time = fs_file_detail[apply_path_type].LastStatusChangeTime; |
| } else { |
| *last_mod_time = 0; |
| MD_TRC_MCF_TR_GET_FILE_LAST_MOD_TIME_FAIL(L4C_MCF_PATH_TYPE_OTA, fs_api_ret[L4C_MCF_PATH_TYPE_OTA]); |
| mcf_ret = MCF_OTA_R_READ_OTA_FILE_FAIL; |
| return mcf_ret; |
| } |
| |
| return mcf_ret; |
| } |
| |
| void mcf_dump_important_info(void) |
| { |
| mcf_t *pMcf = mcf_get_instance(); |
| mcf_ota_file_t *ota_file = &(pMcf->ota_file); |
| mcf_tlvota_file_t *tlvota_file; |
| kal_uint8 path_type; |
| kal_char relative_path_name[MCF_FILE_MAX_NAME_LEN]; |
| kal_uint8 i = 0; |
| |
| MCF_R_LOCK_OBJECT(ota_file, mcf_enhmutex_g); |
| if (ota_file) { |
| path_type = ota_file->path_type; |
| strncpy(relative_path_name, ota_file->relative_path_name, MCF_FILE_MAX_NAME_LEN - 1); |
| MD_TRC_MCF_TR_DUMP_IMPORTANT_INFO_OTA_FILE(path_type, relative_path_name); |
| MCF_R_UNLOCK_OBJECT(ota_file, mcf_enhmutex_g); |
| } else { |
| MD_TRC_MCF_TR_DUMP_IMPORTANT_INFO_TAKE_READ_LOCK_FAIL(); |
| } |
| |
| for (i = 0; i < MAX_SIM_NUM; i++) { |
| tlvota_file = &(pMcf->tlvota_file[i]); |
| MCF_R_LOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| if (tlvota_file) { |
| path_type = tlvota_file->path_type; |
| strncpy(relative_path_name, tlvota_file->relative_path_name, MCF_FILE_MAX_NAME_LEN - 1); |
| MD_TRC_MCF_TR_DUMP_IMPORTANT_INFO_TLVOTA_FILE(i, path_type, relative_path_name); |
| MCF_R_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| } else { |
| MD_TRC_MCF_TR_DUMP_IMPORTANT_INFO_TAKE_READ_LOCK_FAIL(); |
| } |
| } |
| |
| tlvota_file = &(pMcf->general_tlvota_file); |
| MCF_R_LOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| if (tlvota_file) { |
| path_type = tlvota_file->path_type; |
| strncpy(relative_path_name, tlvota_file->relative_path_name, MCF_FILE_MAX_NAME_LEN - 1); |
| MD_TRC_MCF_TR_DUMP_IMPORTANT_INFO_GENERAL_TLVOTA_FILE(path_type, relative_path_name); |
| MCF_R_UNLOCK_OBJECT(tlvota_file, mcf_enhmutex_g); |
| } else { |
| MD_TRC_MCF_TR_DUMP_IMPORTANT_INFO_TAKE_READ_LOCK_FAIL(); |
| } |
| |
| } |
| |
| kal_int32 mcf_atoi(const void *src) |
| { |
| kal_int32 res=0; |
| kal_int8 *p_src=(kal_int8*)src; |
| |
| while( *p_src>='0' && *p_src<='9' ){ |
| res = res*10 + (*p_src - '0'); |
| p_src++; |
| } |
| |
| return res; |
| } |
| |
| kal_int32 mcf_str_strcmp(const void *str1, const void *str2) |
| { |
| kal_int8 *p_str1=(kal_int8*)str1, *p_str2=(kal_int8*)str2; |
| |
| if( p_str1==NULL || p_str2==NULL ){ |
| return 1; |
| } |
| |
| while(*p_str1==*p_str2 && *p_str1!='\0'){ |
| p_str1++; |
| p_str2++; |
| } |
| return *p_str1 - *p_str2; |
| } |
| |
| void mcf_remove_spaces_and_carrier_return(kal_char* src) |
| { |
| kal_char* str1 = src; |
| kal_char* str2 = src; |
| while(*str2 != 0) |
| { |
| |
| *str1 = *str2++; |
| |
| /* 32 = space, 13 = "\r" */ |
| /* Windows uses \r\n to a new line, Linux uses \n to a new line */ |
| |
| if(*str1 != 32 && *str1 != 13){ |
| str1++; |
| } |
| } |
| *str1 = 0; |
| |
| } |
| |
| void mcf_toupper(kal_char* src) |
| { |
| kal_uint32 k = 0; |
| while(src[k] != 0) |
| { |
| if(src[k] >= 'a' && src[k] <= 'z'){ |
| src[k] = src[k]-32; |
| } |
| k++; |
| } |
| |
| } |
| |
| kal_int32 mcf_str_strlen(const void *src) |
| { |
| kal_int8 *p_src=(kal_int8*)src; |
| kal_int32 len=0; |
| |
| if( p_src==NULL ){ |
| return 0; |
| } |
| |
| while('\0' != *p_src){ |
| len++; |
| p_src++; |
| } |
| return len; |
| } |
| |
| kal_bool mcf_hex_str_reverse(kal_char *str, kal_uint32 length) |
| { |
| kal_char temp1; |
| kal_char temp2; |
| kal_uint32 i; |
| |
| if(str == NULL || length < 0 || length %2 != 0){ |
| return KAL_FALSE; |
| } |
| |
| if(length < 4){ |
| return KAL_TRUE; |
| } |
| |
| for(i = 0; i < length/2; i+=2){ |
| temp1 = str[i]; |
| str[i] = str[length-2-i]; |
| str[length-2-i] = temp1; |
| |
| temp2 = str[i+1]; |
| str[i+1] = str[length-1-i]; |
| str[length-1-i] = temp2; |
| } |
| |
| return KAL_TRUE; |
| } |
| |
| kal_int16 mcf_binary_search_lid(kal_uint16 find_lid, kal_uint16 *lid_arr, kal_uint16 lid_size, kal_uint16 *new_pos) |
| { |
| kal_int16 first = 0, // First array element |
| last = lid_size - 1, // Last array element |
| middle = 0, // Mid point of search |
| position = -1; // Position of search value |
| kal_bool found = KAL_FALSE; // Flag |
| |
| while (!found && first <= last) |
| { |
| middle = (first + last) / 2; // Calculate mid point |
| if(middle < 0) |
| return -1; |
| if (lid_arr[middle] == find_lid) // If value is found at mid |
| { |
| found = KAL_TRUE; |
| position = middle; |
| } |
| else if (lid_arr[middle] > find_lid){ // If value is in lower half |
| last = middle - 1; |
| *new_pos = middle; |
| } |
| else{ |
| first = middle + 1; // If value is in upper half |
| *new_pos = first; |
| } |
| } |
| if(lid_size == 0){ |
| *new_pos = 0; |
| } |
| |
| |
| return position; |
| } |
| |
| kal_bool mcf_insert_lid(kal_uint16 new_lid, kal_uint16 *lid_arr, kal_uint16 lid_size, kal_uint16 new_pos) |
| { |
| kal_bool ret = KAL_TRUE; |
| kal_uint16 i = 0; |
| if (lid_size >= NVRAM_MCF_SAVE_LAST_LID_CNT){ |
| ret = KAL_FALSE; |
| return ret; |
| } |
| |
| for(i = lid_size; i > new_pos; i--){ |
| lid_arr[i] = lid_arr[i-1]; |
| } |
| lid_arr[new_pos] = new_lid; |
| |
| return ret; |
| } |
| |
| #ifdef __MCF_COMBINE_FILE_SUPPORT__ |
| kal_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) |
| { |
| kal_int16 first = 0, // First array element |
| last = lid_size - 1, // Last array element |
| middle = 0, // Mid point of search |
| position = -1; // Position of search value |
| kal_bool found = KAL_FALSE; // Flag |
| |
| while (!found && first <= last) |
| { |
| middle = (first + last) / 2; // Calculate mid point |
| if(middle < 0) |
| return -1; |
| if (lid_conf[middle].lid == find_lid) // If value is found at mid |
| { |
| found = KAL_TRUE; |
| position = middle; |
| } |
| else if (lid_conf[middle].lid > find_lid){ // If value is in lower half |
| last = middle - 1; |
| *new_pos = middle; |
| } |
| else{ |
| first = middle + 1; // If value is in upper half |
| *new_pos = first; |
| } |
| } |
| if(lid_size == 0){ |
| *new_pos = 0; |
| } |
| |
| |
| return position; |
| } |
| |
| kal_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) |
| { |
| kal_bool ret = KAL_TRUE; |
| kal_uint16 i = 0; |
| if (lid_size >= NVRAM_MCF_SAVE_LAST_LID_CNT){ |
| ret = KAL_FALSE; |
| return ret; |
| } |
| |
| for(i = lid_size; i > new_pos; i--){ |
| kal_mem_cpy(&lid_conf[i], &lid_conf[i-1], sizeof(nvram_mcf_lid_config_struct)); |
| } |
| lid_conf[new_pos].lid = new_lid; |
| lid_conf[new_pos].not_reset = not_reset; |
| lid_conf[new_pos].set_combined = set_combined; |
| |
| return ret; |
| } |
| |
| kal_bool mcf_clear_last_modified_lid(nvram_mcf_lid_config_struct *lid_conf, kal_uint16 *lid_size) |
| { |
| kal_bool ret = KAL_TRUE; |
| kal_uint16 i = 0; |
| kal_uint16 index = 0; |
| kal_uint16 lid_cnt = 0; |
| kal_uint16 total_cnt = 0; |
| |
| lid_cnt = *lid_size; |
| |
| if (lid_cnt >= NVRAM_MCF_SAVE_LAST_LID_CNT){ |
| ret = KAL_FALSE; |
| return ret; |
| } |
| |
| for(i = 0; i < lid_cnt; i++){ |
| |
| if(lid_conf[i].set_combined == KAL_TRUE ){ |
| kal_mem_set(&lid_conf[i], 0, sizeof(nvram_mcf_lid_config_struct)); |
| index++; |
| while(index < lid_cnt && lid_conf[index].set_combined == KAL_TRUE){ |
| kal_mem_set(&lid_conf[index], 0, sizeof(nvram_mcf_lid_config_struct)); |
| index++; |
| } |
| } |
| |
| if (index < lid_cnt && i != index){ |
| kal_mem_cpy(&lid_conf[i], &lid_conf[index], sizeof(nvram_mcf_lid_config_struct)); |
| kal_mem_set(&lid_conf[index], 0, sizeof(nvram_mcf_lid_config_struct)); |
| total_cnt++; |
| }else if(i == index){ |
| total_cnt++; |
| } |
| |
| index ++; |
| |
| } |
| |
| *lid_size = total_cnt; |
| |
| |
| return ret; |
| } |
| #endif |
| |
| kal_int8* mcf_bytes_to_hex(const void *bytes, kal_int32 length, kal_bool upperCase, void *hex) |
| { |
| kal_int8 *p_hex=(kal_int8*)hex, *p_bytes=(kal_int8*)bytes; |
| kal_int8 LCaseHexArray[] = "0123456789abcdef"; |
| kal_int8 UCaseHexArray[] = "0123456789ABCDEF"; |
| kal_uint32 i=0, v=0; |
| kal_mem_set(p_hex, 0, length*2 + 1); |
| |
| if (p_bytes == NULL) { |
| return NULL; |
| } |
| |
| for (i=0; i<length; i++) { |
| v=p_bytes[i]&0xFF; |
| if( v<0 || (v>>4)>=sizeof(LCaseHexArray) || (v&0x0F)>=sizeof(LCaseHexArray) || (v>>4) < 0 || (v&0x0F) < 0){ |
| return NULL; |
| } else if( upperCase ){ |
| p_hex[i*2] = UCaseHexArray[v >> 4]; |
| p_hex[i*2 + 1] = UCaseHexArray[v & 0x0F]; |
| } else{ |
| p_hex[i*2] = LCaseHexArray[v >> 4]; |
| p_hex[i*2 + 1] = LCaseHexArray[v & 0x0F]; |
| } |
| |
| } |
| return p_hex; |
| } |
| |
| kal_int8* mcf_hex_to_bytes(const void *hex, kal_int32 *length, void *bytes) |
| { |
| kal_int8 *p_hex=(kal_int8*)hex, *p_bytes=(kal_int8*)bytes; |
| kal_int32 len_hex=mcf_str_strlen(p_hex), i=0, j=0; |
| kal_int8 temp[2]; |
| |
| //EXT_ASSERT(len_hex%2==0, len_hex, bytes, 0); |
| if( len_hex%2==1 || len_hex<0 ){ |
| return NULL; |
| } |
| |
| kal_mem_set(p_bytes, 0, len_hex / 2); |
| *length = 0; |
| |
| for( i=0; i<(len_hex/2); i++ ) { |
| temp[0] = p_hex[i * 2]; |
| temp[1] = p_hex[i * 2 + 1]; |
| |
| for (j=0; j<2; j++) { |
| if (temp[j] >= 'A' && temp[j] <= 'F') { |
| temp[j] = temp[j] - 'A' + 10; |
| } else if (temp[j] >= 'a' && temp[j] <= 'f') { |
| temp[j] = temp[j] - 'a' + 10; |
| } else if (temp[j] >= '0' && temp[j] <= '9') { |
| temp[j] = temp[j] - '0'; |
| } else { |
| return NULL; |
| } |
| } |
| p_bytes[i] = (temp[0]<<4) | temp[1]; |
| } |
| *length = len_hex / 2; |
| |
| return p_bytes; |
| } |
| |
| void mcf_replace_char(kal_char* src, kal_char old_ch, kal_char new_ch) |
| { |
| kal_uint32 k = 0; |
| while(src[k] != 0) |
| { |
| if(src[k] == old_ch){ |
| src[k] = new_ch; |
| } |
| k++; |
| } |
| |
| } |
| |
| void mcf_snprintf(kal_char * str, size_t num, const char * fmt, ...) |
| { |
| kal_int32 ret_snprintf = 0; |
| va_list arglist; |
| |
| va_start(arglist, fmt); |
| ret_snprintf = vsnprintf(str, num, fmt, arglist); |
| va_end(arglist); |
| if (ret_snprintf < 0 || ret_snprintf > num){ |
| strncpy(str, "unknown error", num - 1); |
| MD_TRC_MCF_TR_MCF_SNPRINTF_FAIL(num, ret_snprintf); |
| } |
| } |
| |
| #ifdef __MCF_FIND_TAG_SUPPORT__ |
| extern MCF_DB_LID_MAPPING mcf_db_lid_mapping_tbl[]; |
| extern MCF_DB_STRUCT_IDX mcf_db_struct_idx_tbl[]; |
| kal_int32 mcf_parser_binary_search_struct_list(char *find_string, MCF_DB_STRUCT_VARIABLE const *struct_ptr, kal_uint32 struct_size) |
| { |
| kal_int32 first = 0, // First array element |
| last = struct_size - 1, // Last array element |
| middle, // Mid point of search |
| position = -1; // Position of search value |
| kal_bool found = KAL_FALSE; // Flag |
| |
| while (!found && first <= last) |
| { |
| middle = (first + last) / 2; // Calculate mid point |
| if(middle < 0) |
| return -1; |
| if (mcf_str_strcmp(struct_ptr[middle].variable_name, find_string) == 0) // If value is found at mid |
| { |
| found = KAL_TRUE; |
| position = middle; |
| } |
| else if (mcf_str_strcmp(struct_ptr[middle].variable_name, find_string) > 0) // If value is in lower half |
| last = middle - 1; |
| else |
| first = middle + 1; // If value is in upper half |
| } |
| return position; |
| } |
| #endif |
| kal_bool mcf_find_tag_offset( |
| kal_uint32 lid_num, |
| char *tag_name, |
| kal_uint16 *byte_offset, |
| kal_uint16 *bit_offset, |
| kal_uint32 *size, |
| MCF_DB_STRUCT_VARIABLE const **var_ptr, |
| mcf_tag_info_struct *tag_ptr) |
| { |
| #ifdef __MCF_FIND_TAG_SUPPORT__ |
| kal_uint16 i = 0; |
| kal_uint16 array_size_cnt = 1; |
| kal_int32 lid_idx = -1, struct_idx = -1; |
| char *saveptr = NULL, *saveptr2 = NULL, *varstr = NULL, *substr = NULL; |
| char var_name[MAX_VAR_LEN] = {0}; |
| kal_bool next_is_bit = KAL_FALSE; |
| kal_uint32 start_time = GET_CURRENT_TIME(); |
| |
| if(tag_name == NULL || byte_offset == NULL || bit_offset == NULL || size == NULL) |
| { |
| MD_TRC_MCF_TR_FIND_TAG_ERROR_INPUT_NULL(); |
| return KAL_FALSE; |
| } |
| |
| *byte_offset = 0; |
| *bit_offset = 0; |
| *size= 0; |
| dhl_print_string(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_MCF, tag_name); |
| |
| for(i = 0 ; i < MCF_LID_MAPPING_TBL_SIZE ; i++) |
| { |
| if(mcf_db_lid_mapping_tbl[i].lid_num == lid_num) |
| { |
| lid_idx = i; |
| struct_idx = mcf_db_lid_mapping_tbl[i].struct_idx; |
| break; |
| } |
| } |
| |
| // can not find this lid_num in mcf_db_lid_mapping_tbl |
| if(lid_idx == -1 || struct_idx > MCF_STRUCT_LIST_TBL_SIZE) |
| { |
| MD_TRC_MCF_TR_FIND_TAG_ERROR_CAN_NOT_FIND_LID_NUM(lid_num, struct_idx); |
| return KAL_FALSE; |
| } |
| |
| // split "." for each variable |
| substr = kal_strtok_r(tag_name, ".", &saveptr); |
| while (substr){ |
| kal_int32 pos = -1; |
| MCF_DB_STRUCT_VARIABLE const *var_struct_ptr = NULL; |
| |
| // split "[" for get array num |
| varstr = kal_strtok_r(substr, "[", &saveptr2); |
| if(next_is_bit == KAL_TRUE){ |
| kal_uint32 len = strlen(var_name); |
| var_name[len] = '.'; |
| strcpy(var_name + len + 1, varstr); |
| } |
| else |
| { |
| strcpy(var_name, varstr); |
| } |
| |
| var_struct_ptr = mcf_db_struct_idx_tbl[struct_idx].struct_ptr; |
| pos = mcf_parser_binary_search_struct_list(var_name, var_struct_ptr, mcf_db_struct_idx_tbl[struct_idx].struct_size); |
| if(pos == -1) |
| { |
| MCF_BOOT_TRACE(MCF_BOOT_TR_FIND_TAG_ERROR_CAN_NOT_FIND_TAG); |
| MD_TRC_MCF_TR_FIND_TAG_ERROR_CAN_NOT_FIND_TAG(); |
| dhl_print_string(TRACE_ERROR, DHL_USER_FLAG_NONE, MOD_MCF, var_name); |
| return KAL_FALSE; |
| } |
| |
| // get array size |
| if(next_is_bit == KAL_TRUE) |
| { |
| *bit_offset += var_struct_ptr[pos].bit_offset; |
| *size = var_struct_ptr[pos].total_size; |
| } |
| else |
| { |
| kal_uint32 array_size; |
| kal_uint8 i = 0; |
| tag_ptr->arr_cnt = 0; |
| *byte_offset += var_struct_ptr[pos].byte_offset; |
| *size = var_struct_ptr[pos].variable_size; |
| |
| varstr = kal_strtok_r(NULL, "[", &saveptr2); |
| if(varstr != NULL){ |
| do{ |
| kal_uint8 j = 0; |
| kal_uint32 n = 1; |
| array_size = mcf_atoi(varstr); |
| j = i+1; |
| while(var_struct_ptr[pos].array_size[j] != 0) |
| { |
| n *= (var_struct_ptr[pos].array_size[j]); |
| j++; |
| array_size_cnt++; |
| } |
| i++; |
| *byte_offset += (array_size * n * var_struct_ptr[pos].variable_size); |
| tag_ptr->array_size[tag_ptr->arr_cnt] = array_size; |
| tag_ptr->arr_cnt++; |
| }while((varstr = kal_strtok_r(NULL, "[", &saveptr2)) != NULL); |
| |
| if (i > array_size_cnt){ |
| MD_TRC_MCF_TR_FIND_TAG_ERROR_OVER_SIZE(i, array_size_cnt); |
| dhl_print_string(TRACE_ERROR, DHL_USER_FLAG_NONE, MOD_MCF, var_name); |
| return KAL_FALSE; |
| } |
| } |
| else{ |
| *size = var_struct_ptr[pos].total_size; |
| } |
| } |
| |
| if(var_struct_ptr[pos].is_bit) |
| { |
| next_is_bit = KAL_TRUE; |
| tag_ptr->is_bit = KAL_TRUE; |
| tag_ptr->upper_vsize = var_struct_ptr[pos].variable_size; |
| } |
| |
| if(var_struct_ptr[pos].struct_idx != -1) |
| { |
| struct_idx = var_struct_ptr[pos].struct_idx; |
| } |
| |
| substr = kal_strtok_r(NULL, ".", &saveptr); |
| if (substr != 0){ |
| tag_ptr->arr_cnt = 0; |
| kal_mem_set(tag_ptr->array_size, 0, 5); |
| } |
| *var_ptr = &var_struct_ptr[pos]; |
| }; |
| |
| MD_TRC_MCF_TR_FIND_TAG_RETURN_VALUE(lid_num, *byte_offset, *bit_offset, *size, CALCULATE_LETENCY_DURATION(start_time, GET_CURRENT_TIME())); |
| |
| return KAL_TRUE; |
| #else |
| return KAL_FALSE; |
| #endif |
| } |
| |
| #ifdef __MCF_FIND_GID_SUPPORT__ |
| extern MCF_DB_GID_LIST_STRUCT MCF_DB_GID_LIST[]; |
| extern MCF_DB_GID_FORMULA_STRUCT MCF_DB_FORMULA_LIST[]; |
| kal_int32 mcf_gid_binary_search_gid_list(kal_uint32 gid) |
| { |
| kal_int32 first = 0, // First array element |
| last = MCF_MAX_GID_LIST_SIZE - 1, // Last array element |
| middle, // Mid point of search |
| position = -1; // Position of search value |
| kal_bool found = KAL_FALSE; // Flag |
| |
| while (!found && first <= last) |
| { |
| middle = (first + last) / 2; // Calculate mid point |
| if(middle < 0) |
| return -1; |
| if (gid == MCF_DB_GID_LIST[middle].gid) // If value is found at mid |
| { |
| found = KAL_TRUE; |
| position = middle; |
| } |
| else if (gid < MCF_DB_GID_LIST[middle].gid) // If value is in lower half |
| last = middle - 1; |
| else |
| first = middle + 1; // If value is in upper half |
| } |
| return position; |
| } |
| kal_int32 mcf_gid_binary_search_gid_formula_list(kal_uint32 gid) |
| { |
| kal_int32 first = 0, // First array element |
| last = MCF_MAX_GID_FORMULA_LIST_SIZE - 1, // Last array element |
| middle, // Mid point of search |
| position = -1; // Position of search value |
| kal_bool found = KAL_FALSE; // Flag |
| |
| while (!found && first <= last) |
| { |
| middle = (first + last) / 2; // Calculate mid point |
| if(middle < 0) |
| return -1; |
| if (gid == MCF_DB_FORMULA_LIST[middle].gid) // If value is found at mid |
| { |
| found = KAL_TRUE; |
| position = middle; |
| } |
| else if (gid < MCF_DB_FORMULA_LIST[middle].gid) // If value is in lower half |
| last = middle - 1; |
| else |
| first = middle + 1; // If value is in upper half |
| } |
| return position; |
| } |
| #endif |
| kal_bool mcf_find_gid_offset( |
| kal_uint32 gid, |
| char *array_idx_string, |
| kal_uint16 *lid_num, |
| kal_uint16 *byte_offset, |
| kal_uint16 *bit_offset, |
| kal_uint32 *size, |
| kal_bool *is_bit |
| ) |
| { |
| #ifdef __MCF_FIND_GID_SUPPORT__ |
| kal_int32 gid_list_pos = 0, gid_formula_list_pos = 0; |
| kal_uint32 start_time = GET_CURRENT_TIME(); |
| |
| if(byte_offset == NULL || bit_offset == NULL || size == NULL || is_bit == NULL || array_idx_string == NULL) |
| { |
| MD_TRC_MCF_TR_FIND_GID_ERROR_INPUT_NULL(); |
| return KAL_FALSE; |
| } |
| |
| MD_TRC_MCF_TR_FIND_GID_START(gid, array_idx_string); |
| |
| gid_list_pos = mcf_gid_binary_search_gid_list(gid); |
| if(gid_list_pos == -1 || gid_list_pos < 0) |
| { |
| MCF_BOOT_TRACE(MCF_BOOT_TR_FIND_GID_ERROR_CAN_NOT_FIND_GID, gid); |
| MD_TRC_MCF_TR_FIND_GID_ERROR_CAN_NOT_FIND_GID(gid); |
| return KAL_FALSE; |
| } |
| |
| *lid_num = MCF_DB_GID_LIST[gid_list_pos].lid_num; |
| *size = MCF_DB_GID_LIST[gid_list_pos].variable_size; |
| *is_bit = MCF_DB_GID_LIST[gid_list_pos].is_bit; |
| *bit_offset = MCF_DB_GID_LIST[gid_list_pos].bit_offset; |
| if(MCF_DB_GID_LIST[gid_list_pos].array_formula == KAL_FALSE) |
| { |
| *byte_offset = MCF_DB_GID_LIST[gid_list_pos].byte_offset; |
| } |
| else |
| { |
| kal_int32 array_size[10] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; |
| kal_uint32 i = 0, j = 0; |
| kal_uint32 current_array_i = 0; |
| char *saveptr = NULL, *saveptr2 = NULL, *varstr = NULL, *substr = NULL; |
| char gid_formula_string[MCF_MAX_FORMULA_LEN] = {0}; |
| char temp_array_idx[64] = {0}; |
| |
| *byte_offset = 0; |
| strncpy(temp_array_idx, array_idx_string, 63); |
| temp_array_idx[63] = '\0'; |
| // parsing array_idx_string |
| varstr = kal_strtok_r(temp_array_idx, "$", &saveptr); |
| if(varstr != NULL){ |
| do{ |
| array_size[i++] = mcf_atoi(varstr); |
| if(i >= 10) |
| { |
| MCF_BOOT_TRACE(MCF_BOOT_TR_FIND_GID_ERROR_FORMULA_OUT_OF_BOUND , gid); |
| MD_TRC_MCF_TR_FIND_GID_ERROR_FORMULA_OUT_OF_BOUND(gid); |
| dhl_print_string(TRACE_ERROR, DHL_USER_FLAG_NONE, MOD_MCF, temp_array_idx); |
| return KAL_FALSE; |
| } |
| }while((varstr = kal_strtok_r(NULL, "$", &saveptr)) != NULL); |
| |
| } |
| |
| gid_formula_list_pos = mcf_gid_binary_search_gid_formula_list(gid); |
| if(gid_formula_list_pos == -1 || gid_formula_list_pos < 0) |
| { |
| MCF_BOOT_TRACE(MCF_BOOT_TR_FIND_GID_ERROR_CAN_NOT_FIND_FORMULA, gid); |
| MD_TRC_MCF_TR_FIND_GID_ERROR_CAN_NOT_FIND_FORMULA(gid); |
| return KAL_FALSE; |
| } |
| |
| //[5](0,164)+[8](4,20)+[5](0,4)+0 |
| //[10](0,12)+2+2 |
| //[2,8,2](4,2) |
| strncpy(gid_formula_string, MCF_DB_FORMULA_LIST[gid_formula_list_pos].byte_offset_formula, MCF_MAX_FORMULA_LEN - 1); |
| substr = kal_strtok_r(gid_formula_string, "+", &saveptr); |
| if(substr != NULL){ |
| do{ |
| kal_int32 max_array_idx[5] = {-1,-1,-1,-1,-1}; |
| kal_uint32 local_base = 0, local_size = 0, base = 0; |
| kal_uint32 max_array_i = 0; |
| kal_bool max_array_start = KAL_FALSE, local_start = KAL_FALSE, base_start = KAL_TRUE; |
| char temp[20] = {0}; |
| |
| j = 0; |
| while(substr[j] != '\0') |
| { |
| if(substr[j] == '['){ |
| max_array_start = KAL_TRUE; local_start = KAL_FALSE; base_start = KAL_FALSE; |
| kal_mem_set(temp, 0, 20); |
| i = 0; |
| } |
| else if(substr[j] == ']'){ |
| max_array_start = KAL_FALSE; local_start = KAL_FALSE; base_start = KAL_FALSE; |
| varstr = kal_strtok_r(temp, ",", &saveptr2); |
| if(varstr != NULL){ |
| do{ |
| max_array_idx[max_array_i++] = mcf_atoi(varstr); |
| }while((varstr = kal_strtok_r(NULL, ",", &saveptr2)) != NULL); |
| } |
| } |
| else if(substr[j] == '('){ |
| max_array_start = KAL_FALSE; local_start = KAL_TRUE; base_start = KAL_FALSE; |
| kal_mem_set(temp, 0, 20); |
| i = 0; |
| } |
| else if(substr[j] == ')'){ |
| max_array_start = KAL_FALSE; local_start = KAL_FALSE; base_start = KAL_FALSE; |
| varstr = kal_strtok_r(temp, ",", &saveptr2); |
| if (varstr != NULL){ |
| local_base = mcf_atoi(varstr); |
| } |
| varstr = kal_strtok_r(NULL, ",", &saveptr2); |
| if (varstr != NULL){ |
| local_size = mcf_atoi(varstr); |
| } |
| } |
| else // digit |
| { |
| // get max array idx |
| if(max_array_start == KAL_TRUE) |
| { |
| temp[i++] = substr[j]; |
| } |
| else if(local_start == KAL_TRUE) |
| { |
| temp[i++] = substr[j]; |
| } |
| else if(base_start == KAL_TRUE) |
| { |
| base = mcf_atoi(substr); |
| } |
| } |
| |
| j++; |
| } |
| { |
| kal_uint32 temp_offset = 0; |
| for(i = 0; i< max_array_i; i++) |
| { |
| kal_uint32 array_idx = array_size[current_array_i++]; |
| kal_uint32 array_offset = 0; |
| if(array_idx == -1) break; |
| array_offset = array_idx * local_size; |
| |
| if(array_idx >= max_array_idx[i]) |
| { |
| return KAL_FALSE; // array size error |
| } |
| for(j = i + 1 ; j < 5 ; j++) |
| { |
| if(max_array_idx[j] == -1) break; |
| array_offset *= max_array_idx[j]; |
| } |
| temp_offset += array_offset; |
| |
| } |
| *byte_offset += temp_offset + local_base; |
| |
| } |
| *byte_offset += base; |
| |
| }while((substr = kal_strtok_r(NULL, "+", &saveptr)) != NULL); |
| } |
| |
| |
| } |
| |
| 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())); |
| |
| return KAL_TRUE; |
| #else |
| return KAL_FALSE; |
| #endif |
| } |
| |
| kal_uint16 mcf_find_gid_return_lid_num(kal_uint32 gid) |
| { |
| #ifdef __MCF_FIND_GID_SUPPORT__ |
| kal_int32 gid_list_pos = 0; |
| gid_list_pos = mcf_gid_binary_search_gid_list(gid); |
| if(gid_list_pos == -1 || gid_list_pos < 0) |
| { |
| MCF_BOOT_TRACE(MCF_BOOT_TR_FIND_GID_RETURN_LID_NUM_ERROR_CAN_NOT_FIND_GID, gid); |
| MD_TRC_MCF_TR_FIND_GID_RETURN_LID_NUM_ERROR_CAN_NOT_FIND_GID(gid); |
| return -1; // not found |
| } |
| return MCF_DB_GID_LIST[gid_list_pos].lid_num; |
| #else |
| return -1; |
| #endif |
| } |
| |
| kal_uint32 mcf_calc_check_sum(kal_uint32 *ptr, kal_uint32 len) |
| { |
| kal_uint32 check_sum = 0, i = 0; |
| for(i = 0; i< (len/sizeof(kal_uint32)) ; i++, ptr++) |
| check_sum += *ptr; |
| check_sum = ~check_sum + 1; |
| return check_sum; |
| } |
| kal_uint32 mcf_check_check_sum(kal_uint32 *ptr, kal_uint32 len) |
| { |
| kal_uint32 check_sum = 0, i = 0; |
| for(i = 0; i< (len/sizeof(kal_uint32)) ; i++, ptr++) |
| check_sum += *ptr; |
| |
| if(check_sum != 0) |
| MD_TRC_MCF_TR_CHECKSUM_ERROR(check_sum); |
| |
| return check_sum; |
| } |
| |
| // password will be auto padding to 16B |
| // content should be padding to 16B alignment |
| // conrent length should be mod by 16 |
| kal_bool mcf_encrypt_128bit(char *password, char *content, kal_uint32 content_length) |
| { |
| kal_uint8 iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; |
| kal_uint8 copy_len = 0; |
| kal_uint32 output_len; |
| t_cust_chl_sym_key key; |
| AES_PARAM aes_param; |
| kal_uint32 ret = CUST_CHL_ERROR_NONE; |
| kal_uint32 start_time = ust_get_current_time(); |
| |
| if(content == NULL) return KAL_FALSE; |
| if(content_length % 16 != 0) return KAL_FALSE; |
| |
| copy_len = strlen(password); |
| if(copy_len > 16) copy_len = 16; |
| |
| key.m_key_len = 16; |
| kal_mem_set(key.m_key, 0, sizeof(key.m_key)); |
| kal_mem_cpy(&key.m_key, password, copy_len); |
| aes_param.IVLength = 16; |
| aes_param.IV = iv; |
| 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); |
| |
| MD_TRC_MCF_TR_ENCRYPT(ust_us_duration(start_time, ust_get_current_time())); |
| if (ret != CUST_CHL_ERROR_NONE) |
| return KAL_FALSE; |
| return KAL_TRUE; |
| } |
| |
| // password will be auto padding to 16B |
| // content should be padding to 16B alignment |
| // conrent length should be mod by 16 |
| kal_bool mcf_decrypt_128bit(char *password, char *content, kal_uint32 content_length) |
| { |
| kal_uint8 iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; |
| kal_uint8 copy_len = 0; |
| kal_uint32 output_len; |
| t_cust_chl_sym_key key; |
| AES_PARAM aes_param; |
| kal_uint32 ret = CUST_CHL_ERROR_NONE; |
| kal_uint32 start_time = ust_get_current_time(); |
| |
| if(content == NULL) return KAL_FALSE; |
| if(content_length % 16 != 0) return KAL_FALSE; |
| |
| copy_len = strlen(password); |
| if(copy_len > 16) copy_len = 16; |
| |
| key.m_key_len = 16; |
| kal_mem_set(key.m_key, 0, sizeof(key.m_key)); |
| kal_mem_cpy(&key.m_key, password, copy_len); |
| aes_param.IVLength = 16; |
| aes_param.IV = iv; |
| 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); |
| |
| MD_TRC_MCF_TR_DECRYPT(ust_us_duration(start_time, ust_get_current_time())); |
| if (ret != CUST_CHL_ERROR_NONE) |
| return KAL_FALSE; |
| |
| return KAL_TRUE; |
| } |
| #ifdef __MCF_COMBINE_FILE_SUPPORT__ |
| void 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) |
| { |
| if(pre_node != NULL) pre_node->next_node = insert_node; |
| if(next_node != NULL) next_node->pre_node = insert_node; |
| insert_node->pre_node = pre_node; |
| insert_node->next_node = next_node; |
| insert_node->data = insert_data; |
| MD_TRC_MCF_TR_MERGE_LINK_LIST_INSERT_NODE_INFO((pre_node != NULL)?(kal_uint32)pre_node->next_node : 0, |
| (next_node != NULL)?(kal_uint32)next_node->pre_node : 0, |
| (kal_uint32)insert_node->pre_node, (kal_uint32)insert_node->next_node); |
| } |
| |
| // comparison sequence : LID => RID => GID => array idx |
| kal_int8 mcf_merge_compare_ota_data(mcf_tool_gid_ota_file_item_t *first_data, mcf_tool_gid_ota_file_item_t *second_data) |
| { |
| kal_uint16 first_lid_num = mcf_find_gid_return_lid_num(first_data->global_id); |
| kal_uint16 second_lid_num = mcf_find_gid_return_lid_num(second_data->global_id); |
| kal_int32 array_cmp_result = 0; |
| |
| 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); |
| |
| if(first_lid_num < second_lid_num) return -1; |
| else if (first_lid_num > second_lid_num) return 1; |
| |
| if(first_data->record_idx < second_data->record_idx) return -1; |
| else if (first_data->record_idx > second_data->record_idx) return 1; |
| |
| if(first_data->global_id < second_data->global_id) return -1; |
| else if (first_data->global_id > second_data->global_id) return 1; |
| |
| if (first_data->array_index_len > 0) |
| { |
| array_cmp_result= strncmp(&(first_data->buff_start), &(second_data->buff_start), first_data->array_index_len); |
| MD_TRC_MCF_TR_MERGE_CMP_OTA_DATA_ARRAY_INFO(array_cmp_result); |
| if (array_cmp_result < 0) return -1; |
| if (array_cmp_result > 0) return 1; |
| } |
| |
| return 0; |
| } |
| |
| kal_int8 mcf_merge_compare_ota_by_op_tag(char *tag1, char *tag2) |
| { |
| kal_uint16 tag1_sbpid= 0, tag1_mcc=0, tag1_mnc=0, tag2_sbpid=0, tag2_mcc=0, tag2_mnc=0; // use 0 as "NA" |
| kal_char sbp_id_tag[MCF_MAX_TAG_NUM] = {0}; |
| const char *delim = "_"; |
| char * pch; |
| kal_char *saveptr = NULL; |
| // parsing tag1 |
| strncpy(sbp_id_tag, tag1, MCF_MAX_TAG_NUM-1); |
| pch = kal_strtok_r(sbp_id_tag, delim, &saveptr); |
| if (pch != NULL && strcmp(pch, "NA") != 0) tag1_sbpid = mcf_atoi(pch); |
| pch = kal_strtok_r(NULL, delim, &saveptr); |
| if (pch != NULL && strcmp(pch, "NA") != 0) tag1_mcc = mcf_atoi(pch); |
| pch = kal_strtok_r(NULL, delim, &saveptr); |
| if (pch != NULL && strcmp(pch, "NA") != 0) tag1_mnc = mcf_atoi(pch); |
| // parsing tag2 |
| strncpy(sbp_id_tag, tag2, MCF_MAX_TAG_NUM-1); |
| pch = kal_strtok_r(sbp_id_tag, delim, &saveptr); |
| if (pch != NULL && strcmp(pch, "NA") != 0) tag2_sbpid = mcf_atoi(pch); |
| pch = kal_strtok_r(NULL, delim, &saveptr); |
| if (pch != NULL && strcmp(pch, "NA") != 0) tag2_mcc = mcf_atoi(pch); |
| pch = kal_strtok_r(NULL, delim, &saveptr); |
| if (pch != NULL && strcmp(pch, "NA") != 0) tag2_mnc = mcf_atoi(pch); |
| |
| // comparion |
| // SBP |
| if ((tag1_sbpid == tag2_sbpid) && (tag1_mcc == tag2_mcc) && (tag1_mnc == tag2_mnc)) |
| return 0; |
| else if (tag1_sbpid > tag2_sbpid) |
| return 1; |
| else if (tag1_sbpid < tag2_sbpid) |
| return -1; |
| else |
| { |
| // SBP is equal, then compare MCC |
| if (tag1_mcc > tag2_mcc) return 1; |
| else if (tag1_mcc < tag2_mcc) return -1; |
| else |
| { |
| // SBP and MCC are equal, then compare MNC |
| if (tag1_mnc > tag2_mnc) return 1; |
| else if (tag1_mnc < tag2_mnc) return -1; |
| } |
| } |
| return 0; |
| } |
| |
| // comparison sequence : LID => TAG type=> TAG => GID => array idx |
| kal_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) |
| { |
| kal_uint16 first_lid_num = mcf_find_gid_return_lid_num(first_data->global_id); |
| kal_uint16 second_lid_num = mcf_find_gid_return_lid_num(second_data->global_id); |
| kal_int32 array_cmp_result = 0; |
| |
| 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); |
| |
| if(first_lid_num < second_lid_num) return -1; |
| else if (first_lid_num > second_lid_num) return 1; |
| |
| if(first_data->tag_type < second_data->tag_type) return -1; |
| else if (first_data->tag_type > second_data->tag_type) return 1; |
| |
| { |
| kal_char sbp_tag1[MCF_FILE_MAX_TAG_LEN] = {0}; |
| kal_char sbp_tag2[MCF_FILE_MAX_TAG_LEN] = {0}; |
| kal_int8 result= 0; |
| |
| strncpy(sbp_tag1, &(first_data->buff_start) , first_data->tag_len); |
| strncpy(sbp_tag2, &(second_data->buff_start) , second_data->tag_len); |
| |
| result= mcf_merge_compare_ota_by_op_tag(sbp_tag1, sbp_tag2); |
| if(result < 0) return -1; |
| if(result > 0) return 1; |
| } |
| |
| if(first_data->global_id < second_data->global_id) return -1; |
| else if (first_data->global_id > second_data->global_id) return 1; |
| |
| if (first_data->array_index_len > 0) |
| { |
| 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); |
| MD_TRC_MCF_TR_MERGE_CMP_OTA_DATA_ARRAY_INFO(array_cmp_result); |
| if (array_cmp_result < 0) return -1; |
| if (array_cmp_result > 0) return 1; |
| } |
| |
| return 0; |
| } |
| |
| // sort by ascending |
| mcf_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) |
| { |
| mcf_merge_link_list_struct *current_node = head->next_node; |
| mcf_merge_link_list_struct *new_node = NULL; |
| kal_int8 result = 0; |
| 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); |
| 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); |
| |
| if (current != NULL) |
| { |
| // quick determine |
| if (type == MCF_TYPE_OTA) |
| { |
| result = mcf_merge_compare_ota_data((mcf_tool_gid_ota_file_item_t *)insert_data, (mcf_tool_gid_ota_file_item_t *)current->data); |
| } |
| else if (type == MCF_TYPE_OTA_BY_OP) |
| { |
| 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); |
| } |
| else |
| { |
| DEBUG_ASSERT(0); |
| return NULL; |
| } |
| MD_TRC_MCF_TR_MERGE_LINK_LIST_INSERT_CMP_RESULT(result); |
| // if insert data >= current, then start from current. |
| // if insert data < current, back to head to find again. |
| if (result == 1 || result == 0) { |
| current_node = current; |
| MD_TRC_MCF_TR_MERGE_LINK_LIST_USE_CURRENT_AS_START(); |
| } |
| else { |
| current_node = head->next_node; |
| MD_TRC_MCF_TR_MERGE_LINK_LIST_USE_HEAD_AS_START(); |
| } |
| } |
| |
| while (current_node != tail) |
| { |
| // ========= COMPARE NODE ========= |
| result = 0; |
| if (type == MCF_TYPE_OTA) |
| { |
| 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); |
| } |
| else if (type == MCF_TYPE_OTA_BY_OP) |
| { |
| 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); |
| } |
| else |
| { |
| DEBUG_ASSERT(0); |
| return NULL; |
| } |
| MD_TRC_MCF_TR_MERGE_LINK_LIST_INSERT_CMP_RESULT(result); |
| // ========= INSERT NODE ========= |
| // insert data should be inserted BEFORE current node |
| if (result == -1) |
| { |
| new_node = mcf_malloc(sizeof(mcf_merge_link_list_struct)); |
| if(new_node == NULL) return NULL; |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_ALLOCATE((kal_uint32)new_node); |
| kal_mem_set(new_node, 0, sizeof(mcf_merge_link_list_struct)); |
| mcf_merge_insert_node(current_node->pre_node, current_node, new_node, insert_data); |
| return current_node->pre_node; |
| } |
| // insert data should be REPLACED current node |
| else if (result == 0) |
| { |
| current_node->data = insert_data; |
| return current_node; |
| } |
| // insert data should be inserted AFTER current node |
| else if (result == 1) |
| { |
| // due to the link list is acending, skip |
| } |
| else |
| DEBUG_ASSERT(0); |
| |
| current_node = current_node->next_node; |
| } |
| |
| // insert the last |
| new_node = mcf_malloc(sizeof(mcf_merge_link_list_struct)); |
| if(new_node == NULL) return NULL; |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_ALLOCATE((kal_uint32)new_node); |
| kal_mem_set(new_node, 0, sizeof(mcf_merge_link_list_struct)); |
| mcf_merge_insert_node(current_node->pre_node, current_node, new_node, insert_data); |
| |
| return current_node->pre_node; |
| } |
| |
| void mcf_merge_link_list_free(mcf_merge_link_list_struct *head) |
| { |
| mcf_merge_link_list_struct *current = head; |
| while (current != NULL) |
| { |
| mcf_merge_link_list_struct *next = current->next_node; |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_FREE((kal_uint32)current); |
| mcf_free(current); |
| current = next; |
| } |
| } |
| |
| kal_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) |
| { |
| mcf_tool_file_info_t *file_header = (mcf_tool_file_info_t *)buffer; |
| kal_uint32 item_cnt = 0; |
| mcf_merge_link_list_struct *current = NULL; |
| |
| if (type == MCF_TYPE_OTA) { |
| mcf_tool_gid_ota_file_item_t *current_data = (mcf_tool_gid_ota_file_item_t *)((kal_uint8 *)file_header + file_header->total_len); |
| MD_TRC_MCF_TR_MERGE_READ_BUFFER_TO_LINKLIST_TOTAL_ITEM(file_header->item_num); |
| for (item_cnt = 0 ; item_cnt < file_header->item_num ; item_cnt ++) |
| { |
| current = mcf_merge_link_list_insert(head, tail, current, current_data, type); |
| if(current == NULL) return KAL_FALSE; |
| MD_TRC_MCF_TR_MERGE_READ_BUFFER_TO_LINKLIST_ITEM_INFO(item_cnt, current_data->global_id); |
| current_data = (mcf_tool_gid_ota_file_item_t *)((kal_uint8 *)current_data + current_data->total_len); |
| } |
| } |
| else if (type == MCF_TYPE_OTA_BY_OP) |
| { |
| mcf_tool_gid_tlvota_file_item_t *current_data = (mcf_tool_gid_tlvota_file_item_t *)((kal_uint8 *)file_header + file_header->total_len); |
| MD_TRC_MCF_TR_MERGE_READ_BUFFER_TO_LINKLIST_TOTAL_ITEM(file_header->item_num); |
| for (item_cnt = 0 ; item_cnt < file_header->item_num ; item_cnt ++) |
| { |
| current = mcf_merge_link_list_insert(head, tail, current, current_data, type); |
| if(current == NULL) return KAL_FALSE; |
| MD_TRC_MCF_TR_MERGE_READ_BUFFER_TO_LINKLIST_ITEM_INFO(item_cnt, current_data->global_id); |
| current_data = (mcf_tool_gid_tlvota_file_item_t *)((kal_uint8 *)current_data + current_data->total_len); |
| } |
| } |
| else |
| { |
| DEBUG_ASSERT(0); |
| return KAL_FALSE; |
| } |
| return KAL_TRUE; |
| } |
| |
| void mcf_merge_make_ota_file_header(mcf_tool_file_info_t *output_header, mcf_tool_file_info_t *copy_header) |
| { |
| kal_char sw_version[MCF_SW_VERNO_LEN] = {0}; |
| kal_char gen_time[MCF_FILE_MAX_GEN_TIME_LEN] = {0}; |
| |
| struct tm current_time; |
| |
| #if defined(__MTK_TARGET__) && defined(__SUPPORT_CLIB_TIME__) |
| time_t currenttime; |
| kal_mem_set(¤t_time, 0, sizeof(struct tm)); |
| if (time(¤ttime) != -1) |
| localtime_r(¤ttime, ¤t_time); |
| #else |
| current_time.tm_year = 118; |
| current_time.tm_mon = 0; |
| current_time.tm_mday = 1; |
| current_time.tm_hour = 0; |
| current_time.tm_min = 0; |
| current_time.tm_sec = 0; |
| #endif |
| MD_TRC_MCF_TR_MERGE_MAKE_OTA_FILE_HEADER_START(); |
| kal_mem_set(output_header, 0, sizeof(mcf_tool_file_info_t)); |
| |
| kal_mem_set(sw_version, 0, sizeof(kal_char) * MCF_SW_VERNO_LEN); |
| kal_mem_set(gen_time, 0, sizeof(kal_char) * MCF_FILE_MAX_GEN_TIME_LEN); |
| |
| 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) |
| DEBUG_ASSERT(0); |
| strncpy(sw_version, release_verno(), MCF_SW_VERNO_LEN-1); |
| |
| output_header->sw_version_len = strlen(sw_version); |
| output_header->gen_time_len = strlen(gen_time); |
| output_header->file_version = copy_header->file_version; |
| output_header->operation_mask = copy_header->operation_mask; |
| if((output_header->operation_mask & MCF_FILE_OP_SHA256_RSA2048) || (output_header->operation_mask & MCF_FILE_OP_SHA384_RSA3072)) |
| { |
| output_header->operation_mask &= ~(MCF_FILE_OP_SHA256_RSA2048); |
| output_header->operation_mask &= ~(MCF_FILE_OP_SHA384_RSA3072); |
| } |
| strcpy(output_header->file_type, copy_header->file_type); |
| // copy header |
| { |
| // use copy_len to prevent out of array |
| kal_uint32 copy_len = 0; |
| if (output_header->sw_version_len >= MCF_SW_VERNO_LEN -1) copy_len = MCF_SW_VERNO_LEN -1; |
| else copy_len = output_header->sw_version_len; |
| strncpy(&output_header->buff_start, sw_version, copy_len); |
| |
| if (output_header->gen_time_len >= MCF_FILE_MAX_GEN_TIME_LEN -1) copy_len = MCF_FILE_MAX_GEN_TIME_LEN -1; |
| else copy_len = output_header->gen_time_len; |
| strncpy(&output_header->buff_start + output_header->sw_version_len, gen_time, copy_len); |
| } |
| 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 |
| if ((output_header->total_len % 4) != 0) |
| output_header->total_len += 4 - (output_header->total_len % 4); // 4 bytes alignment |
| MD_TRC_MCF_TR_MERGE_MAKE_OTA_FILE_HEADER_END(); |
| } |
| |
| // if first buffer has same gid, it will be replaced by second_buffer |
| kal_bool mcf_merge_ota_buffer(void *first_buffer, void *second_buffer, void *output_buffer, kal_uint32 output_buffer_size) |
| { |
| mcf_merge_link_list_struct *head, *tail; |
| mcf_ota_type_enum type = 0; |
| kal_bool ret = KAL_FALSE; |
| kal_uint32 coreID = kal_get_current_core_id(); |
| |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_START(); |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_MCF_CORE(coreID); |
| //If MCF is running on Core0, need to wake up Core1 to run other task |
| if (coreID == 0){ |
| SleepDrv_LockSleep( SLEEP_CTL_MCF, CORE1); |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_LOCK_CORE(CORE1, coreID); |
| } |
| if (first_buffer == NULL || second_buffer == NULL || output_buffer == NULL) { |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_INPUT_PARAM_ERROR((kal_uint32)first_buffer, (kal_uint32)second_buffer, (kal_uint32)output_buffer); |
| if (coreID == 0){ |
| SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1); |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID); |
| } |
| return KAL_FALSE; |
| } |
| |
| // head init |
| head = mcf_malloc(sizeof(mcf_merge_link_list_struct)); |
| tail = mcf_malloc(sizeof(mcf_merge_link_list_struct)); |
| if(head == NULL || tail == NULL){ |
| if (coreID == 0){ |
| SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1); |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID); |
| } |
| return KAL_FALSE; |
| } |
| kal_mem_set(head, 0, sizeof(mcf_merge_link_list_struct)); |
| kal_mem_set(tail, 0, sizeof(mcf_merge_link_list_struct)); |
| head->next_node = tail; |
| tail->pre_node = head; |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_ALLOCATE_HEAD_TAIL((kal_uint32)head, (kal_uint32)tail); |
| // ========== read first buffer ========== |
| { |
| mcf_tool_file_info_t *file_header = (mcf_tool_file_info_t *)first_buffer; |
| if (strcmp(file_header->file_type, MCF_FILE_TYPE_OTA) == 0) type = MCF_TYPE_OTA; |
| else if (strcmp(file_header->file_type, MCF_FILE_TYPE_TLVOTA) == 0) type = MCF_TYPE_OTA_BY_OP; |
| else{ |
| DEBUG_ASSERT(0); |
| if (coreID == 0){ |
| SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1); |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID); |
| } |
| return KAL_FALSE; |
| } |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_FIRST_BUFFER_TYPE(type); |
| ret = mcf_merge_read_buffer_to_linklist(first_buffer, head, tail, type); |
| if(ret == KAL_FALSE){ |
| if (coreID == 0){ |
| SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1); |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID); |
| } |
| return KAL_FALSE; |
| } |
| } |
| // ========== read second buffer ========== |
| { |
| mcf_tool_file_info_t *file_header = (mcf_tool_file_info_t *)second_buffer; |
| if (strcmp(file_header->file_type, MCF_FILE_TYPE_OTA) == 0) type = MCF_TYPE_OTA; |
| else if (strcmp(file_header->file_type, MCF_FILE_TYPE_TLVOTA) == 0) type = MCF_TYPE_OTA_BY_OP; |
| else{ |
| DEBUG_ASSERT(0); |
| if (coreID == 0){ |
| SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1); |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID); |
| } |
| return KAL_FALSE; |
| } |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_SECOND_BUFFER_TYPE(type); |
| ret = mcf_merge_read_buffer_to_linklist(second_buffer, head, tail, type); |
| if(ret == KAL_FALSE){ |
| if (coreID == 0){ |
| SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1); |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID); |
| } |
| return KAL_FALSE; |
| } |
| } |
| // ========== output buffer ========== |
| { |
| mcf_tool_file_info_t *copy_header = (mcf_tool_file_info_t *)second_buffer; |
| mcf_tool_file_info_t *output_header = (mcf_tool_file_info_t *)output_buffer; |
| kal_uint8 *current_pos = NULL; |
| mcf_merge_link_list_struct *current_node = head->next_node; |
| |
| mcf_merge_make_ota_file_header(output_header, copy_header); // copy first header to output header |
| current_pos = (kal_uint8 *)output_header + output_header->total_len; |
| |
| if (strcmp(output_header->file_type, MCF_FILE_TYPE_OTA) == 0) type = MCF_TYPE_OTA; |
| else if (strcmp(output_header->file_type, MCF_FILE_TYPE_TLVOTA) == 0) type = MCF_TYPE_OTA_BY_OP; |
| else{ |
| DEBUG_ASSERT(0); |
| if (coreID == 0){ |
| SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1); |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID); |
| } |
| return KAL_FALSE; |
| } |
| |
| while (current_node != tail) |
| { |
| if (type == MCF_TYPE_OTA) |
| { |
| mcf_tool_gid_ota_file_item_t *current_ota_data = current_node->data; |
| kal_mem_cpy(current_pos, current_ota_data, current_ota_data->total_len); |
| current_pos += current_ota_data->total_len; |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_OUTPUT_GID(current_ota_data->global_id); |
| mcf_dump_data(KAL_FALSE, ¤t_ota_data->buff_start + current_ota_data->array_index_len, current_ota_data->value_len); |
| } |
| else if (type == MCF_TYPE_OTA_BY_OP) |
| { |
| mcf_tool_gid_tlvota_file_item_t *current_ota_by_data = current_node->data; |
| kal_mem_cpy(current_pos, current_ota_by_data, current_ota_by_data->total_len); |
| current_pos += current_ota_by_data->total_len; |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_OUTPUT_GID(current_ota_by_data->global_id); |
| mcf_dump_data(KAL_FALSE, ¤t_ota_by_data->buff_start + current_ota_by_data->tag_len + current_ota_by_data->array_index_len, current_ota_by_data->value_len); |
| } |
| current_node = current_node->next_node; |
| output_header->item_num++; |
| output_header->file_size = (kal_uint32)((kal_uint8 *)current_pos - (kal_uint8 *)output_header); |
| if (output_header->file_size > output_buffer_size) |
| { |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_OUTPUT_BUFFER_OUT_OF_SIZE(output_header->file_size, output_buffer_size); |
| if (coreID == 0){ |
| SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1); |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID); |
| } |
| return KAL_FALSE; |
| } |
| } |
| |
| if ((output_header->operation_mask & MCF_FILE_OP_AES_128) || (output_header->operation_mask & MCF_FILE_OP_AES_256)) |
| { |
| if (((output_header->file_size - output_header->total_len) % 16) != 0) |
| output_header->file_size += 16 - (output_header->file_size - output_header->total_len) % 16; // content should be 16 bytes alignment |
| } |
| else if (((output_header->file_size - output_header->total_len) % 4) != 0) |
| { |
| output_header->file_size += 4 - (output_header->file_size - output_header->total_len) % 4; // content should be 4 bytes alignment |
| } |
| |
| } |
| |
| // ========== security ========== |
| { |
| mcf_tool_file_info_t *file_header = (mcf_tool_file_info_t *)output_buffer; |
| // checksum |
| if (file_header->operation_mask & MCF_FILE_OP_CHECKSUM) |
| { |
| file_header->checksum = 0; |
| file_header->checksum = mcf_calc_check_sum((kal_uint32 *)output_buffer, file_header->file_size); |
| } |
| // encrypt |
| if (file_header->operation_mask & MCF_FILE_OP_AES_128) |
| { |
| kal_char password[MCF_MAX_PASSWORD_LEN] = {0}; |
| mcf_get_custom_aes_password(password); |
| 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) |
| { |
| if (coreID == 0){ |
| SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1); |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID); |
| } |
| return KAL_FALSE; |
| } |
| } |
| else if (file_header->operation_mask & MCF_FILE_OP_AES_256) |
| { |
| kal_char password[MCF_MAX_PASSWORD_LEN] = {0}; |
| mcf_get_custom_aes_password(password); |
| 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) |
| { |
| if (coreID == 0){ |
| SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1); |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID); |
| } |
| return KAL_FALSE; |
| } |
| } |
| } |
| |
| mcf_merge_link_list_free(head); |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_END(); |
| if (coreID == 0){ |
| SleepDrv_UnlockSleep( SLEEP_CTL_MCF, CORE1); |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_UNLOCK_CORE(CORE1, coreID); |
| } |
| return KAL_TRUE; |
| } |
| |
| // NOTE : if this gid needs to merge to a file, call mcf_merge_ota_buffer to combine this buffer |
| kal_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) |
| { |
| MD_TRC_MCF_TR_MERGE_ONE_GID_START(); |
| if (new_gid == NULL || output_buffer == NULL) { |
| MD_TRC_MCF_TR_MERGE_ONE_GID_INPUT_PARAM_ERROR((kal_uint32)new_gid, (kal_uint32)output_buffer); |
| return KAL_FALSE; |
| } |
| |
| mcf_tool_file_info_t copy_header; |
| mcf_tool_file_info_t *output_header = (mcf_tool_file_info_t *)output_buffer; |
| kal_uint32 gid_size = 0; |
| copy_header.file_version = 3; |
| copy_header.operation_mask = operation_mask; |
| mcf_merge_make_ota_file_header(output_header, ©_header); // copy first header to output header |
| if (type == MCF_TYPE_OTA) |
| { |
| strcpy(output_header->file_type, MCF_FILE_TYPE_OTA); |
| mcf_tool_gid_ota_file_item_t *ota = new_gid; |
| gid_size = ota->total_len; |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_OUTPUT_GID(ota->global_id); |
| mcf_dump_data(KAL_FALSE, &ota->buff_start + ota->array_index_len, ota->value_len); |
| } |
| else if (type == MCF_TYPE_OTA_BY_OP) |
| { |
| strcpy(output_header->file_type, MCF_FILE_TYPE_TLVOTA); |
| mcf_tool_gid_tlvota_file_item_t *ota_by_op = new_gid; |
| gid_size = ota_by_op->total_len; |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_OUTPUT_GID(ota_by_op->global_id); |
| 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); |
| } |
| else |
| { |
| return KAL_FALSE; |
| } |
| // check buffer size |
| if ((output_header->total_len + gid_size) > output_buffer_size) { |
| MD_TRC_MCF_TR_MERGE_OTA_BUFFER_OUTPUT_BUFFER_OUT_OF_SIZE((output_header->total_len + gid_size), output_buffer_size); |
| return KAL_FALSE; |
| } |
| |
| kal_mem_cpy((kal_uint8 *)output_buffer + output_header->total_len, new_gid, gid_size); |
| output_header->item_num = 1; |
| output_header->file_size = (kal_uint32)((kal_uint8 *)output_buffer + output_header->total_len + gid_size - (kal_uint8 *)output_header); |
| if (((output_header->file_size - output_header->total_len) % 4) != 0) |
| output_header->file_size += 4 - (output_header->file_size - output_header->total_len) % 4; // content should be 16 bytes alignment |
| // ========== security ========== |
| { |
| mcf_tool_file_info_t *file_header = (mcf_tool_file_info_t *)output_buffer; |
| // checksum |
| if (file_header->operation_mask & MCF_FILE_OP_CHECKSUM) |
| { |
| file_header->checksum = 0; |
| file_header->checksum = mcf_calc_check_sum((kal_uint32 *)output_buffer, file_header->file_size); |
| } |
| // encrypt |
| if (file_header->operation_mask & MCF_FILE_OP_AES_128 || file_header->operation_mask & MCF_FILE_OP_AES_256) |
| { |
| // this output is temp buffer, no need to encrypt |
| file_header->operation_mask &= ~(MCF_FILE_OP_AES_128); |
| file_header->operation_mask &= ~(MCF_FILE_OP_AES_256); |
| } |
| } |
| MD_TRC_MCF_TR_MERG_ONE_GID_END(); |
| return KAL_TRUE; |
| } |
| #endif |
| |
| // password will be auto padding to 32B |
| // content should be padding to 32B alignment |
| // conrent length should be mod by 32 |
| kal_bool mcf_encrypt_256bit(char *password, char *content, kal_uint32 content_length) |
| { |
| kal_uint8 iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; |
| kal_uint8 copy_len = 0; |
| kal_uint32 output_len; |
| t_cust_chl_sym_key key; |
| AES_PARAM aes_param; |
| kal_uint32 ret = CUST_CHL_ERROR_NONE; |
| kal_uint32 start_time = ust_get_current_time(); |
| |
| kal_mem_set(&aes_param, 0, sizeof(AES_PARAM)); |
| |
| if (content == NULL) return KAL_FALSE; |
| if (content_length % 16 != 0) return KAL_FALSE; |
| |
| copy_len = strlen(password); |
| if (copy_len > 32) copy_len = 32; |
| |
| key.m_key_len = 32; |
| kal_mem_set(key.m_key, 0, sizeof(key.m_key)); |
| kal_mem_cpy(&key.m_key, password, copy_len); |
| aes_param.IVLength = 16; |
| aes_param.IV = iv; |
| 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); |
| |
| MD_TRC_MCF_TR_ENCRYPT(ust_us_duration(start_time, ust_get_current_time())); |
| if (ret != CUST_CHL_ERROR_NONE) |
| return KAL_FALSE; |
| |
| return KAL_TRUE; |
| } |
| |
| // password will be auto padding to 32B |
| // content should be padding to 32B alignment |
| // conrent length should be mod by 32 |
| kal_bool mcf_decrypt_256bit(char *password, char *content, kal_uint32 content_length) |
| { |
| kal_uint8 iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; |
| kal_uint8 copy_len = 0; |
| kal_uint32 output_len; |
| t_cust_chl_sym_key key; |
| AES_PARAM aes_param; |
| kal_uint32 ret = CUST_CHL_ERROR_NONE; |
| kal_uint32 start_time = ust_get_current_time(); |
| |
| kal_mem_set(&aes_param, 0, sizeof(AES_PARAM)); |
| |
| if (content == NULL) return KAL_FALSE; |
| if (content_length % 16 != 0) return KAL_FALSE; |
| |
| copy_len = strlen(password); |
| if (copy_len > 32) copy_len = 32; |
| |
| key.m_key_len = 32; |
| kal_mem_set(key.m_key, 0, sizeof(key.m_key)); |
| kal_mem_cpy(&key.m_key, password, copy_len); |
| aes_param.IVLength = 16; |
| aes_param.IV = iv; |
| 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); |
| |
| MD_TRC_MCF_TR_DECRYPT(ust_us_duration(start_time, ust_get_current_time())); |
| if (ret != CUST_CHL_ERROR_NONE) |
| return KAL_FALSE; |
| |
| return KAL_TRUE; |
| } |
| |
| // digest verify |
| kal_bool mcf_verify_digest(kal_uint32 digest_tag, mcf_tool_file_info_t *ota_file, mcf_digest *sign) |
| { |
| kal_uint32 ret = KAL_FALSE; |
| t_cust_chl_asym_key key; |
| |
| if (digest_tag == MCF_FILE_OP_SHA256_RSA2048) { |
| ret = mcf_get_custom_digest_public_key(sign->sequence, &key); |
| if (ret == KAL_FALSE) return KAL_FALSE; |
| 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); |
| } |
| else if(digest_tag == MCF_FILE_OP_SHA384_RSA3072){ |
| ret = mcf_get_custom_digest_public_key(sign->sequence, &key); |
| if (ret == KAL_FALSE) return KAL_FALSE; |
| 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); |
| } |
| else |
| { |
| // not support |
| return KAL_FALSE; |
| } |
| |
| if (ret != CUST_CHL_ERROR_NONE) |
| return KAL_FALSE; |
| |
| return KAL_TRUE; |
| } |
| |
| void 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) |
| { |
| MD_TRC_MCF_TR_MAKE_FILE_INFO_START(path_type, last_mod_time & 0xFFFFFFFF, checksum & 0xFFFFFFFF); |
| |
| kal_mem_set(file_info, 0, sizeof(mcf_file_info_t)); |
| file_info->path_type = path_type; |
| strncpy(file_info->name, name, MCF_FILE_MAX_NAME_LEN-1); |
| strncpy(file_info->sw_version, sw_version, sw_version_len); |
| strncpy(file_info->gen_time, gen_time, gen_time_len); |
| file_info->last_mod_time = last_mod_time; |
| file_info->checksum = checksum; |
| file_info->sw_version_len = sw_version_len; |
| file_info->gen_time_len = gen_time_len; |
| } |
| |
| kal_bool mcf_compare_file_info(mcf_file_info_t *old_file, mcf_file_info_t *new_file) |
| { |
| static nvram_ef_mcf_sw_info_struct nv_sw_info; |
| |
| MD_TRC_MCF_TR_COMPARE_FILE_INFO_START(); |
| MD_TRC_MCF_TR_COMPARE_FILE_INFO_OLD_FILE_INFO(old_file->sw_version, old_file->gen_time); |
| MD_TRC_MCF_TR_COMPARE_FILE_INFO_NEW_FILE_INFO(new_file->sw_version, new_file->gen_time); |
| MD_TRC_MCF_TR_COMPARE_FILE_INFO_FILE_CHECKSUM(old_file->checksum & 0xFFFFFFFF, new_file->checksum & 0xFFFFFFFF); |
| MD_TRC_MCF_TR_COMPARE_FILE_INFO_FILE_LAST_MOD_TIME(old_file->last_mod_time & 0xFFFFFFFF, new_file->last_mod_time & 0xFFFFFFFF); |
| if ( (strncmp(old_file->sw_version, new_file->sw_version, new_file->sw_version_len) == 0) && |
| (strncmp(old_file->gen_time, new_file->gen_time, new_file->gen_time_len) == 0) && |
| (old_file->path_type == new_file->path_type) && |
| (strncmp(old_file->name, new_file->name, MCF_FILE_MAX_NAME_LEN) == 0) && |
| (old_file->last_mod_time == new_file->last_mod_time) && |
| (old_file->checksum == new_file->checksum) ) { |
| |
| if ( !nvram_external_read_data(NVRAM_EF_MCF_SW_INFO_LID, 1, (kal_uint8 *)&nv_sw_info, sizeof(nvram_ef_mcf_sw_info_struct))) { |
| MD_TRC_MCF_TR_COMPARE_FILE_INFO_READ_FILE_NVRAM_FAIL(NVRAM_EF_MCF_SW_INFO_LID); |
| return KAL_FALSE; |
| } |
| |
| if ((strncmp(nv_sw_info.version, release_verno(), MCF_SW_VERNO_LEN) == 0) && |
| (strncmp(nv_sw_info.build_time, build_date_time(), MCF_SW_BUILD_TIME_LEN) == 0)){ |
| MD_TRC_MCF_TR_COMPARE_FILE_INFO_MD_INFO(nv_sw_info.version, nv_sw_info.build_time); |
| return KAL_TRUE; |
| }else{ |
| MD_TRC_MCF_TR_COMPARE_FILE_INFO_FILE_NOT_THE_SAME(); |
| return KAL_FALSE; |
| } |
| }else{ |
| MD_TRC_MCF_TR_COMPARE_FILE_INFO_FILE_NOT_THE_SAME(); |
| return KAL_FALSE; |
| |
| } |
| |
| } |
| |