// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Copyright (c) 2019 Amlogic, Inc. All rights reserved. */ #include #include #include #include #include #include "model_log.h" #include "model_size.h" #define LOG_TAG "model_fs" #define LOG_NDEBUG 0 static char local_file_path[MODEL_FILE_PATH_LEN_MAX]; static char local_part_name[MODEL_FILE_PATH_LEN_MAX]; static char local_file_name[MODEL_FILE_PATH_LEN_MAX]; static char local_directory[MODEL_FILE_PATH_LEN_MAX]; static int split_file_path(const char *file_path) { char *tmp_start_ptr = NULL; char *tmp_end_ptr = NULL; char *tmp_dir_ptr = NULL; char *slot_name, *tmp_ptr; int i = 0; if (!file_path) { ALOGE("%s: file_path is NULL!\n", __func__); goto split_file_path_err; } memset((void *)local_file_path, 0, MODEL_FILE_PATH_LEN_MAX); memset((void *)local_part_name, 0, MODEL_FILE_PATH_LEN_MAX); memset((void *)local_file_name, 0, MODEL_FILE_PATH_LEN_MAX); memset((void *)local_directory, 0, MODEL_FILE_PATH_LEN_MAX); strlcpy(local_file_path, file_path, MODEL_FILE_PATH_LEN_MAX); tmp_start_ptr = strchr(file_path, '/'); if (tmp_start_ptr != file_path) { ALOGE("%s: not abstract file_path: %s\n", __func__, file_path); goto split_file_path_err; } tmp_end_ptr = strchr(tmp_start_ptr + 1, '/'); if (!tmp_end_ptr) { ALOGE("%s: no file_name in file_path: %s\n", __func__, file_path); goto split_file_path_err; } strlcpy(local_part_name, tmp_start_ptr + 1, tmp_end_ptr - tmp_start_ptr); if (has_boot_slot == 1) { slot_name = env_get("slot-suffixes"); if (!slot_name) { run_command("get_valid_slot", 0); slot_name = env_get("slot-suffixes"); } if (strcmp(slot_name, "0") == 0) strcat(local_part_name, "_a"); else if (strcmp(slot_name, "1") == 0) strcat(local_part_name, "_b"); } tmp_start_ptr = tmp_end_ptr; tmp_dir_ptr = tmp_end_ptr; i = 0; while (*tmp_end_ptr) { if (i >= MODEL_FILE_PATH_LEN_MAX) { ALOGE("%s: file_path is too long (%d): %s\n", __func__, i, file_path); goto split_file_path_err; } tmp_end_ptr++; i++; } strlcpy(local_file_name, tmp_start_ptr, i + 1); tmp_ptr = tmp_dir_ptr; while (1) { tmp_ptr = strchr(tmp_ptr + 1, '/'); if (!tmp_ptr) break; tmp_dir_ptr = tmp_ptr; } i = tmp_dir_ptr - tmp_start_ptr; if (i >= MODEL_FILE_PATH_LEN_MAX - 1) { ALOGE("%s: file_path is too long (%d): %s\n", __func__, i, file_path); goto split_file_path_err; } strlcpy(local_directory, tmp_start_ptr, i + 1); ALOGD("%s: partition name: %s, dir: %s, file_name: %s\n", __func__, local_part_name, local_directory, local_file_name + strlen(local_directory) + 1); return 0; split_file_path_err: memset((void *)local_part_name, 0, MODEL_FILE_PATH_LEN_MAX); memset((void *)local_file_name, 0, MODEL_FILE_PATH_LEN_MAX); memset((void *)local_directory, 0, MODEL_FILE_PATH_LEN_MAX); return -1; } #define CS_BLOCK_DEV_INTERFACE "mmc" #define CS_BLOCK_DEV_MARJOR_NUM "1" static int set_block_device(const char *part_name) { int part_no = 0; char part_buf[128] = {0}; char tmp_buf[128] = {0}; int ret; part_no = get_partition_num_by_name(part_name); //ALOGD("%s: part_no: %d\n", __func__, part_no); if (part_no >= 0) { strcpy(part_buf, CS_BLOCK_DEV_MARJOR_NUM); strcat(part_buf, ":"); snprintf(tmp_buf, 127, "%x", part_no); strcat(part_buf, tmp_buf); //ALOGD("%s: %s\n", __func__, part_buf); ret = fs_set_blk_dev(CS_BLOCK_DEV_INTERFACE, part_buf, FS_TYPE_EXT); if (ret) ALOGE("%s: fs_set_blk_dev failed: %s\n", __func__, part_buf); return ret; } ALOGE("%s: partition num error: %s\n", __func__, part_name); return -1; } void model_list_match_files(const char *file_path, char *match_prefix, char *match_ext) { struct fs_dir_stream *dirs = NULL; struct fs_dirent *dent; char *tmp_start_ptr = NULL; int prefix_ok, ext_ok, name_len, middle_len; int prefix_len = (match_prefix ? strlen(match_prefix) : 0); int ext_len = (match_ext ? strlen(match_ext) : 0); if (!file_path) return; if (strcmp(file_path, local_file_path)) { if (split_file_path(file_path) < 0) return; } if (set_block_device(local_part_name) < 0) return; dirs = fs_opendir(local_directory); if (!dirs) { ALOGE("%s: failed to open directory: %s\n", __func__, local_directory); return; } while ((dent = fs_readdir(dirs))) { if (strcmp(dent->name, ".") == 0 || strcmp(dent->name, "..") == 0) continue; if (dent->type == FS_DT_DIR) continue; prefix_ok = 1; ext_ok = 1; name_len = strlen(dent->name); if (prefix_len) { if (name_len < prefix_len || strncmp(dent->name, match_prefix, prefix_len)) prefix_ok = 0; } if (ext_len > 0) { if (name_len < ext_len || strcmp(dent->name + name_len - ext_len, match_ext)) ext_ok = 0; } if (!prefix_ok || !ext_ok) continue; tmp_start_ptr = dent->name + prefix_len; middle_len = name_len - prefix_len - ext_len; printf("%.*s\n", middle_len, tmp_start_ptr); } fs_closedir(dirs); } int model_file_is_exist(const char *file_path) { if (!file_path) return 0; if (strcmp(file_path, local_file_path)) { if (split_file_path(file_path) < 0) return 0; } if (set_block_device(local_part_name) < 0) return 0; return fs_exists(local_file_name); } int model_get_file_size(const char *file_path) { loff_t file_size = 0; if (!file_path) return -1; if (strcmp(file_path, local_file_path)) { if (split_file_path(file_path) < 0) return -1; } if (set_block_device(local_part_name) < 0) return -1; if (fs_size(local_file_name, &file_size)) { ALOGE("%s: file \"%s\" is not exist!\n", __func__, local_file_name); return -1; } if (file_size == 0) ALOGE("%s: file \"%s\" size error!\n", __func__, local_file_name); return file_size; } int model_read_file(const char *file_path, unsigned char *data_buf, int buf_size) { loff_t rd_size = 0; int ret = -1; if (!file_path) return -1; if (strcmp(file_path, local_file_path)) { if (split_file_path(file_path) < 0) return -1; } if (set_block_device(local_part_name) < 0) return -1; ret = fs_read(local_file_name, (unsigned long)data_buf, 0, 0, &rd_size); if (ret < 0) return -1; if (rd_size > buf_size) { ALOGE("%s: %s: rd_size %lld out of buf_size %d\n", __func__, file_path, rd_size, buf_size); return -1; } flush_dcache_range((unsigned long)data_buf, (unsigned long)data_buf + rd_size); ALOGD("%s: %s: rd_size: %lld, buf_size: %d\n", __func__, file_path, rd_size, buf_size); return rd_size; } unsigned char *model_read_file_to_buffer(const char *file_path, int *buf_size) { unsigned char *tmp_buf = NULL; int rd_size = 0, file_size = 0, new_size = 0; file_size = model_get_file_size(file_path); if (file_size <= 0) return NULL; new_size = file_size + 8; //avoid last char not '\0' issue tmp_buf = (unsigned char *)malloc(new_size); if (!tmp_buf) return NULL; memset(tmp_buf, 0, new_size); rd_size = model_read_file(file_path, tmp_buf, file_size); if (rd_size <= 0 || rd_size > file_size) { memset(tmp_buf, 0, new_size); free(tmp_buf); return NULL; } *buf_size = new_size; return tmp_buf; } unsigned char *model_read_bin_to_buffer(const char *file_path, int *buf_size) { unsigned char *tmp_buf = NULL; int rd_size = 0, file_size = 0; file_size = model_get_file_size(file_path); if (file_size <= 0) return NULL; tmp_buf = (unsigned char *)malloc(file_size); if (!tmp_buf) return NULL; memset(tmp_buf, 0, file_size); rd_size = model_read_file(file_path, tmp_buf, file_size); if (rd_size <= 0 || rd_size > file_size) { memset(tmp_buf, 0, file_size); free(tmp_buf); return NULL; } *buf_size = file_size; return tmp_buf; }