Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: R_BSP TLV320_RBSP USBHost_custom
sys_scan_folder.cpp
00001 /******************************************************************************* 00002 * DISCLAIMER 00003 * This software is supplied by Renesas Electronics Corporation and is only 00004 * intended for use with Renesas products. No other uses are authorized. This 00005 * software is owned by Renesas Electronics Corporation and is protected under 00006 * all applicable laws, including copyright laws. 00007 * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING 00008 * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT 00009 * LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE 00010 * AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. 00011 * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS 00012 * ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE 00013 * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR 00014 * ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE 00015 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 00016 * Renesas reserves the right, without notice, to make changes to this software 00017 * and to discontinue the availability of this software. By using this software, 00018 * you agree to the additional terms and conditions found by accessing the 00019 * following link: 00020 * http://www.renesas.com/disclaimer* 00021 * Copyright (C) 2015 Renesas Electronics Corporation. All rights reserved. 00022 *******************************************************************************/ 00023 00024 #include "mbed.h" 00025 #include "FATFileSystem.h" 00026 #include "USBHostMSD.h" 00027 #include "sys_scan_folder.h" 00028 00029 /*--- Macro definition of folder structure scan. ---*/ 00030 /* The character string to identify root directory. */ 00031 #define STR_ROOT_FOR_F_OPENDIR "" /* to use f_opendir() */ 00032 #define STR_ROOT_FOR_FOPEN "/" SYS_USB_MOUNT_NAME /* to use fopen() */ 00033 00034 /* The file extension of FLAC. */ 00035 #define FILE_EXT_FLAC ".flac" 00036 #define FILE_EXT_FLA ".fla" 00037 00038 #define CHR_FULL_STOP '.' /* 0x2E: FULL STOP */ 00039 #define CHR_SOLIDUS '/' /* 0x2F: SOLIDUS */ 00040 #define FOLD_ID_NOT_EXIST (0xFFFFFFFFu) 00041 #define OPEN_MODE_READ_ONLY "r" 00042 00043 /* File path maximum size including the usb mount name size */ 00044 #define USB_MOUNT_NAME_SIZE (sizeof(STR_ROOT_FOR_FOPEN "/")) 00045 #define FILE_PATH_MAX_LEN (60u) 00046 #define FILE_PATH_MAX_SIZE (USB_MOUNT_NAME_SIZE + FILE_PATH_MAX_LEN) 00047 00048 static const char_t *get_full_path(fid_scan_folder_t * const p_info, 00049 const item_t * const p_item); 00050 static bool open_dir(fid_scan_folder_t * const p_info, 00051 const item_t * const p_item, FATFS_DIR * const p_fdir); 00052 static bool read_dir(fid_scan_folder_t * const p_info, FATFS_DIR * const p_fdir, 00053 const char_t ** const p_name, bool * const p_flag_dir); 00054 static bool regist_item(item_t * const p_item, 00055 const char_t * const p_name, const uint32_t parent); 00056 static bool check_extension(const char_t * const p_name); 00057 00058 static bool check_folder_depth(const fid_scan_folder_t * const p_info, 00059 const uint32_t folder_id); 00060 00061 void fid_init(fid_scan_folder_t * const p_info) 00062 { 00063 if (p_info != NULL) { 00064 p_info->total_folder = 0u; 00065 p_info->total_track = 0u; 00066 } 00067 } 00068 00069 bool fid_scan_folder_struct(fid_scan_folder_t * const p_info) 00070 { 00071 bool ret = false; 00072 bool result; 00073 bool chk; 00074 uint32_t i; 00075 item_t *p_item; 00076 FATFS_DIR fdir; 00077 const char_t *p_name; 00078 bool flg_dir; 00079 bool chk_dep; 00080 00081 if (p_info != NULL) { 00082 /* Initializes the scan data. */ 00083 p_info->total_track = 0u; 00084 p_info->total_folder = 0u; 00085 00086 /* Registers the identifier of the root directory to use f_opendir(). */ 00087 (void) regist_item(&p_info->folder_list[0], STR_ROOT_FOR_F_OPENDIR, FOLD_ID_NOT_EXIST); 00088 p_info->total_folder++; 00089 00090 /* Checks the item in all registered directory. */ 00091 for (i = 0; i < p_info->total_folder; i++) { 00092 chk_dep = check_folder_depth(p_info, i); 00093 result = open_dir(p_info, &p_info->folder_list[i], &fdir); 00094 while (result == true) { 00095 result = read_dir(p_info, &fdir, &p_name, &flg_dir); 00096 if (result == true) { 00097 /* Checks the attribute of this item. */ 00098 if (flg_dir == true) { 00099 /* This item is directory. */ 00100 if ((chk_dep == true) && (p_info->total_folder < SYS_MAX_FOLDER_NUM)) { 00101 p_item = &p_info->folder_list[p_info->total_folder]; 00102 chk = regist_item(p_item, p_name, i); 00103 if (chk == true) { 00104 /* Register of directory item was success. */ 00105 p_info->total_folder++; 00106 } 00107 } 00108 } else { 00109 /* This item is file. */ 00110 chk = check_extension(p_name); 00111 if ((chk == true) && (p_info->total_track < SYS_MAX_TRACK_NUM)) { 00112 /* This item is FLAC file. */ 00113 p_item = &p_info->track_list[p_info->total_track]; 00114 chk = regist_item(p_item, p_name, i); 00115 if (chk == true) { 00116 /* Register of file item was success. */ 00117 p_info->total_track++; 00118 } 00119 } 00120 } 00121 } 00122 } 00123 } 00124 /* Changes the identifier of the root directory to use fopen(). */ 00125 (void) regist_item(&p_info->folder_list[0], STR_ROOT_FOR_FOPEN, FOLD_ID_NOT_EXIST); 00126 00127 if (p_info->total_track > 0u) { 00128 ret = true; 00129 } 00130 } 00131 00132 return ret; 00133 } 00134 00135 FILE *fid_open_track(fid_scan_folder_t * const p_info, const uint32_t track_id) 00136 { 00137 FILE *fp = NULL; 00138 const char_t *p_path; 00139 size_t path_len; 00140 00141 if (p_info != NULL) { 00142 if (track_id < p_info->total_track) { 00143 p_path = get_full_path(p_info, &p_info->track_list[track_id]); 00144 if (p_path != NULL) { 00145 path_len = strlen(p_path); 00146 /* File path maximum length is limited by the specification of "fopen". */ 00147 if (path_len < FILE_PATH_MAX_SIZE) { 00148 fp = fopen(p_path, OPEN_MODE_READ_ONLY); 00149 } 00150 } 00151 } 00152 } 00153 return fp; 00154 } 00155 00156 void fid_close_track(FILE * const fp) 00157 { 00158 if (fp != NULL) { 00159 (void) fclose(fp); 00160 } 00161 } 00162 00163 const char_t *fid_get_track_name(const fid_scan_folder_t * const p_info, 00164 const uint32_t track_id) 00165 { 00166 const char_t *p_name = NULL; 00167 00168 if (p_info != NULL) { 00169 if (track_id < p_info->total_track) { 00170 p_name = &p_info->track_list[track_id].name[0]; 00171 } 00172 } 00173 return p_name; 00174 } 00175 00176 uint32_t fid_get_total_track(const fid_scan_folder_t * const p_info) 00177 { 00178 uint32_t ret = 0u; 00179 00180 if (p_info != NULL) { 00181 ret = p_info->total_track; 00182 } 00183 return ret; 00184 } 00185 00186 /** Gets the full path 00187 * 00188 * @param p_info Pointer to the control data of folder scan module. 00189 * @param p_item Pointer to the item structure of the folder / track. 00190 * 00191 * @returns 00192 * Pointer to the full path. 00193 */ 00194 static const char_t *get_full_path(fid_scan_folder_t * const p_info, 00195 const item_t * const p_item) 00196 { 00197 const char_t *p_path = NULL; 00198 const item_t *p; 00199 const item_t *item_list[SYS_MAX_FOLDER_DEPTH]; 00200 uint32_t i; 00201 uint32_t item_cnt; 00202 uint32_t buf_cnt; 00203 uint32_t len; 00204 bool err; 00205 00206 if ((p_info != NULL) && (p_item != NULL)) { 00207 for (i = 0; i < SYS_MAX_FOLDER_DEPTH; i++) { 00208 item_list[i] = NULL; 00209 } 00210 p_info->work_buf[0] = '\0'; 00211 00212 /* Stores the item name until the root folder. */ 00213 p = p_item; 00214 item_cnt = 0; 00215 while ((item_cnt < SYS_MAX_FOLDER_DEPTH) && 00216 (p->parent_number < p_info->total_folder)) { 00217 item_list[item_cnt] = p; 00218 item_cnt++; 00219 p = &p_info->folder_list[p->parent_number]; 00220 } 00221 if (p->parent_number == FOLD_ID_NOT_EXIST) { 00222 buf_cnt = strlen(p->name); 00223 (void) strncpy(&p_info->work_buf[0], p->name, sizeof(p_info->work_buf)); 00224 err = false; 00225 while ((item_cnt > 0u) && (err != true)) { 00226 item_cnt--; 00227 p = item_list[item_cnt]; 00228 /* Concatenates SOLIDUS character to the "work_buf" variable. */ 00229 if ((buf_cnt + 1u) < sizeof(p_info->work_buf)) { 00230 p_info->work_buf[buf_cnt] = CHR_SOLIDUS; 00231 buf_cnt++; 00232 } else { 00233 err = true; 00234 } 00235 /* Concatenates the item name to the "work_buf" variable. */ 00236 if (p != NULL) { 00237 len = strlen(p->name); 00238 if ((buf_cnt + len) < sizeof(p_info->work_buf)) { 00239 (void) strncpy(&p_info->work_buf[buf_cnt], p->name, len); 00240 buf_cnt += len; 00241 } else { 00242 err = true; 00243 } 00244 } 00245 } 00246 if (err != true) { 00247 p_info->work_buf[buf_cnt] = '\0'; 00248 p_path = &p_info->work_buf[0]; 00249 } 00250 } 00251 } 00252 return p_path; 00253 } 00254 00255 /** Opens the directory 00256 * 00257 * @param p_info Pointer to the control data of folder scan module. 00258 * @param p_item Pointer to the item structure of the folder / track. 00259 * @param p_fdir Pointer to the structure to store the directory object. 00260 * 00261 * @returns 00262 * Results of process. true is success. false is failure. 00263 */ 00264 static bool open_dir(fid_scan_folder_t * const p_info, 00265 const item_t * const p_item, FATFS_DIR * const p_fdir) 00266 { 00267 bool ret = false; 00268 const char_t *p_path; 00269 FRESULT ferr; 00270 00271 if ((p_info != NULL) && (p_item != NULL) && (p_fdir != NULL)) { 00272 p_path = get_full_path(p_info, p_item); 00273 if (p_path != NULL) { 00274 ferr = f_opendir(p_fdir, p_path); 00275 if (ferr == FR_OK) { 00276 ret = true; 00277 } 00278 } 00279 } 00280 return ret; 00281 } 00282 00283 /** Reads the directory 00284 * 00285 * @param p_info Pointer to the control data of folder scan module. 00286 * @param p_fdir Pointer to the structure of the directory object. 00287 * @param p_flag_dir Pointer to the variable to store the directory flag. 00288 * 00289 * @returns 00290 * Pointer to the name. 00291 */ 00292 static bool read_dir(fid_scan_folder_t * const p_info, FATFS_DIR * const p_fdir, 00293 const char_t ** const p_name, bool * const p_flag_dir) 00294 { 00295 bool ret = false; 00296 FRESULT ferr; 00297 FILINFO finfo; 00298 00299 if ((p_info != NULL) && (p_fdir != NULL) && 00300 (p_name != NULL) && (p_flag_dir != NULL)) { 00301 /* Sets the buffer to store the long file name. */ 00302 finfo.lfname = &p_info->work_buf[0]; 00303 finfo.lfsize = sizeof(p_info->work_buf); 00304 ferr = f_readdir(p_fdir, &finfo); 00305 if ((ferr == FR_OK) && ((int32_t)finfo.fname[0] != '\0')) { 00306 if (finfo.lfname != NULL) { 00307 if ((int32_t)finfo.lfname[0] == '\0') { 00308 /* Long file name does not exist. */ 00309 (void) strncpy(finfo.lfname, finfo.fname, finfo.lfsize); 00310 } 00311 /* Adds the NULL terminal character. */ 00312 /* This is fail-safe processing. */ 00313 finfo.lfname[finfo.lfsize - 1u] = '\0'; 00314 00315 ret = true; 00316 *p_name = finfo.lfname; 00317 if ((finfo.fattrib & AM_DIR) != 0) { 00318 /* This item is directory. */ 00319 *p_flag_dir = true; 00320 } else { 00321 /* This item is file. */ 00322 *p_flag_dir = false; 00323 } 00324 } 00325 } 00326 } 00327 return ret; 00328 } 00329 00330 /** Registers the item of the folder / track 00331 * 00332 * @param p_item Pointer to the structure to store the item of the folder / track. 00333 * @param p_name Pointer to the name of the item. 00334 * @param parent Number of the parent folder of the item. 00335 * 00336 * @returns 00337 * Results of process. true is success. false is failure. 00338 */ 00339 static bool regist_item(item_t * const p_item, 00340 const char_t * const p_name, const uint32_t parent) 00341 { 00342 bool ret = false; 00343 uint32_t len; 00344 00345 if ((p_item != NULL) && (p_name != NULL)) { 00346 len = strlen(p_name); 00347 if ((len + 1u) < sizeof(p_item->name)) { 00348 (void) strncpy(p_item->name, p_name, sizeof(p_item->name)); 00349 p_item->name[sizeof(p_item->name) - 1u] = '\0'; 00350 p_item->parent_number = parent; 00351 ret = true; 00352 } 00353 } 00354 return ret; 00355 } 00356 00357 /** Checks the extension of the track name 00358 * 00359 * @param p_name Pointer to the name of the track. 00360 * 00361 * @returns 00362 * Results of the checking. true is FLAC file. false is other file. 00363 */ 00364 static bool check_extension(const char_t * const p_name) 00365 { 00366 bool ret = false; 00367 const char_t *p; 00368 00369 if (p_name != NULL) { 00370 p = strrchr(p_name, CHR_FULL_STOP); 00371 if (p != NULL) { 00372 if (strncasecmp(p, FILE_EXT_FLAC, sizeof(FILE_EXT_FLAC)) == 0) { 00373 ret = true; 00374 } else if (strncasecmp(p, FILE_EXT_FLA, sizeof(FILE_EXT_FLA)) == 0) { 00375 ret = true; 00376 } else { 00377 /* DO NOTHING */ 00378 } 00379 } 00380 } 00381 return ret; 00382 } 00383 00384 /** Checks the folder depth in the scan range 00385 * 00386 * @param p_info Pointer to the control data of folder scan module. 00387 * @param folder_id Folder ID [0 - (total folder - 1)] 00388 * 00389 * @returns 00390 * Results of the checking. true is the scan range. false is out of a scan range. 00391 */ 00392 static bool check_folder_depth(const fid_scan_folder_t * const p_info, 00393 const uint32_t folder_id) 00394 { 00395 bool ret = false; 00396 uint32_t depth; 00397 uint32_t parent_id; 00398 00399 if (p_info != NULL) { 00400 /* Counts the folder depth. */ 00401 parent_id = folder_id; 00402 depth = 0u; 00403 while ((depth < SYS_MAX_FOLDER_DEPTH) && 00404 (parent_id < p_info->total_folder)) { 00405 depth++; 00406 parent_id = p_info->folder_list[parent_id].parent_number; 00407 } 00408 if (parent_id == FOLD_ID_NOT_EXIST) { 00409 /* Found the root folder. */ 00410 if (depth < SYS_MAX_FOLDER_DEPTH) { 00411 ret = true; 00412 } 00413 } 00414 } 00415 return ret; 00416 }
Generated on Tue Jul 12 2022 22:07:08 by
1.7.2