499 lines
15 KiB
C
499 lines
15 KiB
C
#ifdef SUPPORT_MS_EXTENSIONS
|
|
#pragma bss_seg(".file_manager.data.bss")
|
|
#pragma data_seg(".file_manager.data")
|
|
#pragma const_seg(".file_manager.text.const")
|
|
#pragma code_seg(".file_manager.text")
|
|
#endif
|
|
#include "file_manager.h"
|
|
#include "app_config.h"
|
|
#include "dev_update.h"
|
|
|
|
#define MODE_FIX 1
|
|
#if MODE_FIX
|
|
static int file_manager_mode_deal(struct vfscan *fs, int sel_mode, int *arg)
|
|
{
|
|
if (fs == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
int fnum = 0;
|
|
int file_start = 1;
|
|
int file_end = fs->file_number;
|
|
|
|
if (file_end == 0) {
|
|
return -ENOENT;
|
|
}
|
|
struct ffolder folder = {0};
|
|
fget_folder(fs, &folder);
|
|
/* if ((scan->cycle_mode == FCYCLE_FOLDER) && (scan->ff_api.fileTotalInDir) */
|
|
/* && ((scan->ff_api.fileTotalOutDir + scan->ff_api.fileTotalInDir) <= scan->ff_api.totalFileNumber) */
|
|
/* ) { */
|
|
|
|
if ((fs->cycle_mode == FCYCLE_FOLDER) && (folder.fileTotal)
|
|
&& ((folder.fileStart + folder.fileTotal - 1) <= file_end)
|
|
) {
|
|
file_start = folder.fileStart;
|
|
file_end = folder.fileStart + folder.fileTotal - 1;
|
|
}
|
|
switch (sel_mode) {
|
|
case FSEL_LAST_FILE:
|
|
fnum = fs->file_number;
|
|
break;
|
|
case FSEL_FIRST_FILE:
|
|
fnum = 1;
|
|
break;
|
|
case FSEL_AUTO_FILE:
|
|
/* if (scan->ff_api.fileNumber == 0) { */
|
|
/* return -EINVAL; */
|
|
/* } */
|
|
if (fs->cycle_mode == FCYCLE_ONE) {
|
|
/* fnum = scan->ff_api.fileNumber; */
|
|
fnum = fs->file_counter;
|
|
break;
|
|
}
|
|
/* break; */
|
|
case FSEL_NEXT_FILE:
|
|
/* if (scan->ff_api.fileNumber == 0) { */
|
|
/* return -EINVAL; */
|
|
/* } */
|
|
if (fs->cycle_mode == FCYCLE_RANDOM) {
|
|
fnum = rand32() % (file_end - file_start + 1) + file_start;
|
|
if (fnum == fs->file_counter) {
|
|
fnum = fs->file_counter + 1;
|
|
}
|
|
} else {
|
|
fnum = fs->file_counter + 1;
|
|
}
|
|
/* if (fnum > scan->last_file_number) { */
|
|
if (fnum > fs->file_number) {
|
|
if (fs->cycle_mode == FCYCLE_LIST) {
|
|
return -ENOENT;
|
|
} else if (fs->cycle_mode == FCYCLE_FOLDER) {
|
|
fnum = file_start;
|
|
} else {
|
|
fnum = 1;
|
|
}
|
|
}
|
|
if (fnum > file_end) {
|
|
fnum = file_start;
|
|
} else if (fnum < file_start) {
|
|
fnum = file_end;
|
|
}
|
|
break;
|
|
case FSEL_PREV_FILE:
|
|
/* if (scan->ff_api.fileNumber == 0) { */
|
|
/* return -EINVAL; */
|
|
/* } */
|
|
if (fs->cycle_mode == FCYCLE_RANDOM) {
|
|
fnum = rand32() % (file_end - file_start + 1) + file_start;
|
|
if (fnum == fs->file_counter) {
|
|
fnum = fs->file_counter + 1;
|
|
}
|
|
} else {
|
|
fnum = fs->file_counter - 1;
|
|
}
|
|
/* if ((scan->ff_api.fileNumber | BIT(15)) != scan->cur_file_number) { */
|
|
/* fnum -= scan->last_file_number - scan->ff_api.totalFileNumber; */
|
|
/* } */
|
|
/* scan->last_file_number = scan->ff_api.totalFileNumber; */
|
|
if (fs->cycle_mode == FCYCLE_LIST) {
|
|
break;
|
|
}
|
|
if (fnum > file_end) {
|
|
fnum = file_start;
|
|
} else if (fnum < file_start) {
|
|
fnum = file_end;
|
|
}
|
|
break;
|
|
|
|
case FSEL_NEXT_FOLDER_FILE:
|
|
/* fnum = scan->ff_api.fileTotalOutDir + scan->ff_api.fileTotalInDir + 1; */
|
|
fnum = folder.fileStart + folder.fileTotal;
|
|
if (fnum > fs->file_number) {
|
|
fnum = 1;
|
|
}
|
|
break;
|
|
case FSEL_PREV_FOLDER_FILE:
|
|
/* if ((scan->ff_api.fileTotalOutDir + 1) > 1) { */
|
|
if (folder.fileStart > 1) {
|
|
fnum = folder.fileStart - 1;
|
|
} else {
|
|
fnum = fs->file_number;
|
|
}
|
|
break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
|
|
if ((sel_mode != FSEL_NEXT_FOLDER_FILE) && (sel_mode != FSEL_PREV_FOLDER_FILE)) {
|
|
if (fnum < file_start) {
|
|
fnum = file_start;
|
|
} else if (fnum > file_end) {
|
|
fnum = file_end;
|
|
}
|
|
}
|
|
*arg = fnum;
|
|
return 0;
|
|
}
|
|
#endif
|
|
//*----------------------------------------------------------------------------*/
|
|
/**@brief 设备文件扫描扫盘
|
|
@param
|
|
dev:设备节点
|
|
path:指定扫描目录
|
|
parm:扫描参数,包括文件后缀等
|
|
cycle_mode:播放循环模式
|
|
callback:扫描打断回调
|
|
@return 成功返回扫描控制句柄,失败返回NULL
|
|
@note
|
|
*/
|
|
/*----------------------------------------------------------------------------*/
|
|
struct vfscan *file_manager_scan_disk(struct __dev *dev, const char *path, const char *parm, u8 cycle_mode, struct __scan_callback *callback)
|
|
{
|
|
if (dev == NULL || dev_manager_check(dev) == NULL) {
|
|
return NULL;
|
|
}
|
|
#if TCFG_USB_DM_MULTIPLEX_WITH_SD_DAT0
|
|
|
|
#if (TCFG_DM_MULTIPLEX_WITH_SD_PORT == 0) //0:sd0 1:sd1 //dm 参与复用的sd配置
|
|
if (!memcmp(dev->parm->logo, "sd0", strlen("sd0"))) {
|
|
#else
|
|
if (!memcmp(dev->parm->logo, "sd1", strlen("sd1"))) {
|
|
#endif
|
|
dev_usb_change_sd();
|
|
}
|
|
|
|
if (!memcmp(dev->parm->logo, "udisk", strlen("udisk"))) {
|
|
dev_sd_change_usb();
|
|
}
|
|
|
|
if (dev_manager_online_check(dev, 1) == NULL) {
|
|
printf("mult remount fail !!!\n");
|
|
return NULL;
|
|
}
|
|
#endif
|
|
char *fsn_path = NULL;
|
|
char *tmp_path = NULL;
|
|
if (path) {
|
|
if (*path == '/') {
|
|
path++;
|
|
}
|
|
tmp_path = zalloc(strlen(dev->parm->root_path) + strlen(path) + 1);
|
|
if (tmp_path == NULL) {
|
|
return NULL;
|
|
}
|
|
sprintf(tmp_path, "%s%s", dev->parm->root_path, path);
|
|
fsn_path = tmp_path;
|
|
} else {
|
|
fsn_path = dev->parm->root_path;
|
|
}
|
|
printf("fsn_path = %s, scan parm = %s\n", fsn_path, parm);
|
|
struct vfscan *fsn;
|
|
/* clock_add_set(SCAN_DISK_CLK); */
|
|
if (callback && callback->enter) {
|
|
callback->enter(dev);//扫描前处理, 可以在注册的回调里提高系统时钟等处理
|
|
}
|
|
fsn = fscan_interrupt(
|
|
(const char *)fsn_path,
|
|
parm,
|
|
FILE_MANAGER_SCAN_DISK_MAX_DEEPTH,
|
|
((callback) ? callback->scan_break : NULL));
|
|
/* clock_remove_set(SCAN_DISK_CLK); */
|
|
if (callback && callback->exit) {
|
|
callback->exit(dev);//扫描后处理, 可以在注册的回调里还原到enter前的状态
|
|
}
|
|
if (fsn) {
|
|
if (fsn->file_number == 0) {
|
|
printf("dev nofile\n");
|
|
#if (TCFG_DEV_UPDATE_IF_NOFILE_ENABLE)
|
|
///没有文件找升级文件
|
|
dev_update_check(dev->parm->logo);
|
|
#endif/*TCFG_DEV_UPDATE_IF_NOFILE_ENABLE*/
|
|
///没有文件,释放fsn, 减少外面流程的处理
|
|
fscan_release(fsn);
|
|
fsn = NULL;
|
|
} else {
|
|
fsn->cycle_mode = cycle_mode;
|
|
}
|
|
}
|
|
|
|
if (tmp_path) {
|
|
free(tmp_path);
|
|
}
|
|
return fsn;
|
|
}
|
|
FILE *file_manager_select(struct __dev *dev, struct vfscan *fs, int sel_mode, int arg, struct __scan_callback *callback)
|
|
{
|
|
FILE *_file = NULL;
|
|
if (dev == NULL) {
|
|
return NULL;
|
|
}
|
|
//clock_add_set(SCAN_DISK_CLK);
|
|
if (callback && callback->enter) {
|
|
callback->enter(dev);//扫描前处理, 可以在注册的回调里提高系统时钟等处理
|
|
}
|
|
#if MODE_FIX
|
|
if ((sel_mode != FSEL_BY_SCLUST) && (sel_mode != FSEL_BY_PATH) && (sel_mode != FSEL_BY_NUMBER)) {
|
|
if (file_manager_mode_deal(fs, sel_mode, &arg)) {
|
|
return NULL;
|
|
}
|
|
sel_mode = FSEL_BY_NUMBER;
|
|
}
|
|
#endif
|
|
_file = fselect(fs, sel_mode, arg);
|
|
//clock_remove_set(SCAN_DISK_CLK);
|
|
if (callback && callback->exit) {
|
|
callback->exit(dev);//扫描后处理, 可以在注册的回调里还原到enter前的状态
|
|
}
|
|
return _file;
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------*/
|
|
/**
|
|
* @brief 文件删除统一处理
|
|
*
|
|
* @param path 扫描路径名
|
|
* @param param 配置参数
|
|
* @param dir_flag 是否删除文件夹标志
|
|
* @note 加速处理:(删除文件的时候使用)从前往后依次删除. 文件夹必须从后往前删。
|
|
*
|
|
* @return 0成功, 其他失败
|
|
*/
|
|
/* ----------------------------------------------------------------------------*/
|
|
int file_manager_delete_deal(char *path, char *param, u8 dir_flag)
|
|
{
|
|
if (path == NULL) {
|
|
r_printf(">>>[test]:err!!!!!! path is NULL\n");
|
|
return 1;
|
|
}
|
|
|
|
if (param == NULL) {
|
|
r_printf(">>>[test]:err!!!!!! param is NULL\n");
|
|
return 1;
|
|
}
|
|
u16 folder_total_file = 0;
|
|
int d_err = 0;
|
|
struct vfscan *fsn = NULL;
|
|
FILE *d_f = NULL;
|
|
|
|
fsn = fscan(path, param, 9);
|
|
if (fsn == NULL) {
|
|
r_printf(">>>[test]:err!!!!!! fsacn fsn fail\n");
|
|
return 1;
|
|
}
|
|
folder_total_file = fsn->file_number;
|
|
y_printf(">>>[test]:total = %d\n", folder_total_file);
|
|
for (int i = folder_total_file; i >= 1; i--) {
|
|
if (!dir_flag) {
|
|
d_f = fselect(fsn, FSEL_BY_NUMBER, folder_total_file - i + 1); //加速处理,不用找到最后一个文件。
|
|
} else {
|
|
d_f = fselect(fsn, FSEL_BY_NUMBER, i);
|
|
}
|
|
if (d_f == NULL) {
|
|
r_printf(">>>[test]:err!! select file err\n");
|
|
return 1;
|
|
}
|
|
putchar('D');
|
|
d_err = fdelete(d_f);
|
|
if (d_err) {
|
|
r_printf(">>>[test]:err!! delete file err\n");
|
|
return 1;
|
|
}
|
|
d_f = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/** @brief:文件夹删除处理
|
|
@param:dev_logo :设备logo folder:文件夹路径(短名) folder_len:文件夹路径长度
|
|
@return:
|
|
@author:phewlee
|
|
@note:
|
|
@date: 2021-05-21,10:16
|
|
*/
|
|
/*----------------------------------------------------------------------------*/
|
|
int file_manager_delete_dir(char *dev_logo, char *folder, u16 folder_len)
|
|
{
|
|
int err = 0;
|
|
struct __dev *dev;
|
|
char path[128] = {0};
|
|
|
|
static const u8 delete_file_param[] = "-t"
|
|
"ALL"
|
|
" -sn -r";
|
|
|
|
static const u8 delete_folder_param[] = "-t"
|
|
"ALL"
|
|
" -sn -d -r";
|
|
|
|
if (dev_logo == NULL) {
|
|
r_printf(">>>[test]:errr!!!!!!!!! dev_logo is NULL\n");
|
|
return 1;
|
|
}
|
|
|
|
if (folder == NULL) {
|
|
r_printf(">>>[test]:errr!!!!!!!!! folder is NULL\n");
|
|
return 1;
|
|
}
|
|
|
|
dev = dev_manager_find_spec(dev_logo, 0);
|
|
if (dev == NULL) {
|
|
r_printf(">>>[test]:errr!!!!!!!!! not find dev\n");
|
|
return 1;
|
|
}
|
|
char *root_path = dev_manager_get_root_path(dev);
|
|
memcpy(path, root_path, strlen(root_path));
|
|
memcpy(path + strlen(root_path), folder, folder_len);
|
|
r_printf(">>>[test]:path = %s\n", path);
|
|
err = file_manager_delete_deal(path, (char *)delete_file_param, 0);
|
|
if (err) {
|
|
r_printf(">>>[test]:errr!!!!!!!!! delete file deal fail\n");
|
|
return 1;
|
|
}
|
|
err = file_manager_delete_deal(path, (char *)delete_folder_param, 1);
|
|
if (err) {
|
|
r_printf(">>>[test]:errr!!!!!!!!! delete folder deal fail\n");
|
|
return 1;
|
|
}
|
|
FILE *folder_f = fopen(path, "r");
|
|
if (folder_f == NULL) {
|
|
r_printf(">>>[test]:err open folder\n");
|
|
return 1;
|
|
}
|
|
err = fdelete(folder_f);
|
|
return err;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/** @brief:文件插入处理
|
|
@param:d_f: 源文件句柄, i_f:插入文件句柄,fptr:偏移量
|
|
@return:
|
|
@author:phewlee
|
|
@note:
|
|
@date: 2021-05-25,10:16
|
|
*/
|
|
/*----------------------------------------------------------------------------*/
|
|
int file_manager_insert_file(FILE *d_f, FILE *i_f, u32 fptr)
|
|
{
|
|
if (d_f == NULL) {
|
|
r_printf(">>>[test]:errr!!!!!!!!! d_f is NULL\n");
|
|
return -1;
|
|
}
|
|
|
|
if (i_f == NULL) {
|
|
r_printf(">>>[test]:errr!!!!!!!!! i_f is NULL\n");
|
|
return -1;
|
|
}
|
|
|
|
int err = finsert_file(d_f, i_f, fptr);
|
|
return err;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/** @brief:文件分割处理
|
|
@param:f: 源文件句柄, dev_logo:设备logo , file_name : 文件名, name_len: 文件长度, fptr:偏移量, buf:头文件数据, buf_len:头文件数据长度, folder : 需要指定的路径,绝对路径,例如:/RECORD或者/1/2/3/4, 暂时只支持短名文件夹形式, folder 传NULL默认根目录。
|
|
@return:
|
|
@author:phewlee
|
|
@note:
|
|
@date: 2021-05-25,10:16
|
|
*/
|
|
/*----------------------------------------------------------------------------*/
|
|
int file_manager_division_file(FILE *f, char *dev_logo, char *file_name, u32 name_len, u32 fptr, char *buf, u32 buf_len, char *folder)
|
|
{
|
|
struct __dev *dev;
|
|
char path[128] = {0};
|
|
char tmp_name[64] = {0};
|
|
if ((dev_logo == NULL) || (file_name == NULL) || (buf == NULL)) {
|
|
return -1;
|
|
}
|
|
|
|
///////////////////////////////////////////////////
|
|
dev = dev_manager_find_spec(dev_logo, 0);
|
|
if (dev == NULL) {
|
|
r_printf(">>>[test]:errr!!!!!!!!! not find dev\n");
|
|
return -1;
|
|
}
|
|
char *root_path = dev_manager_get_root_path(dev);
|
|
|
|
/****************分割文件*********************/
|
|
if (folder) {
|
|
memcpy(tmp_name, folder, strlen(folder));
|
|
}
|
|
strcat(tmp_name, "/");
|
|
strcat(tmp_name, "jl_test.tmp");
|
|
if (fdicvision_file(f, tmp_name, fptr)) {
|
|
r_printf(">>>[test]:file division fail\n");
|
|
goto __exit;
|
|
}
|
|
|
|
/****************打开分割出去的文件*********************/
|
|
memcpy(path, root_path, strlen(root_path) - 1);
|
|
memcpy(path + strlen(root_path) - 1, tmp_name, strlen(tmp_name));
|
|
r_printf(">>>[test]:path1 = %s\n", path);
|
|
FILE *i_f = fopen(path, "r");
|
|
if (i_f == NULL) {
|
|
r_printf(">>>[test]:open i_f fail\n");
|
|
return -1;
|
|
}
|
|
///////////////////////////////////////////////////
|
|
|
|
/****************创建新文件,写入头数据*********************/
|
|
memset(path, 0, sizeof(path));
|
|
memcpy(path, root_path, strlen(root_path));
|
|
if (folder) {
|
|
memcpy(path + strlen(path) - 1, folder, strlen(folder));
|
|
strcat(path, "/");
|
|
}
|
|
memcpy(path + strlen(path), file_name, name_len);
|
|
r_printf(">>>[test]:path1 = %s\n", path);
|
|
FILE *d_f = fopen(path, "w+");
|
|
if (d_f == NULL) {
|
|
r_printf(">>>[test]:open d_f fail\n");
|
|
fclose(i_f);
|
|
i_f = NULL;
|
|
goto __exit;
|
|
}
|
|
int wlen = fwrite(buf, buf_len, 1, d_f);
|
|
if (wlen != buf_len) {
|
|
r_printf(">>>[test]:err write!!!!!!!!wlen = %d, buf_len = %d\n", wlen, buf_len);
|
|
fclose(i_f);
|
|
i_f = NULL;
|
|
fclose(d_f);
|
|
d_f = NULL;
|
|
goto __exit;
|
|
}
|
|
fclose(d_f);
|
|
d_f = NULL;
|
|
d_f = fopen(path, "r");
|
|
if (d_f == NULL) {
|
|
r_printf(">>>[test]:open d_f fail\n");
|
|
fclose(i_f);
|
|
i_f = NULL;
|
|
goto __exit;
|
|
}
|
|
//////////////////////////////////////////////////////////
|
|
|
|
int fsize = flen(d_f);
|
|
int err = finsert_file(d_f, i_f, fsize);
|
|
fclose(i_f);
|
|
i_f = NULL;
|
|
fclose(d_f);
|
|
d_f = NULL;
|
|
return err;
|
|
|
|
__exit:
|
|
memset(path, 0, sizeof(path));
|
|
memcpy(path, root_path, strlen(root_path) - 1);
|
|
memcpy(path + strlen(root_path) - 1, tmp_name, strlen(tmp_name));
|
|
r_printf(">>>[test]:error process: path1 = %s\n", path);
|
|
FILE *f_tmp = fopen(path, "r");
|
|
if (f_tmp) {
|
|
fdelete(f_tmp);
|
|
f_tmp = NULL;
|
|
}
|
|
return -1;
|
|
}
|
|
|