Toyomasa Watarai
/
Mbed-example-WS-W27
Mbed Cloud example program for workshop in W27 2018.
Embed:
(wiki syntax)
Show/hide line numbers
pal_plat_fileSystem.cpp
00001 #include "mbed.h" 00002 00003 #include <errno.h> 00004 #include <stdio.h> 00005 #include <string.h> 00006 #include <stdlib.h> 00007 #include "FATFileSystem.h" 00008 00009 #include "FileSystemLike.h" 00010 #include "FilePath.h" 00011 00012 00013 //PAL Includes 00014 #include "pal.h" 00015 #include "pal_plat_fileSystem.h" 00016 00017 00018 #ifndef EEXIST 00019 #define EEXIST 17 00020 #endif 00021 #ifndef EACCES 00022 #define EACCES 13 00023 #endif 00024 #ifndef EFAULT 00025 #define EFAULT 14 00026 #endif 00027 #ifndef EROFS 00028 #define EROFS 30 00029 #endif 00030 #ifndef EBUSY 00031 #define EBUSY 16 00032 #endif 00033 #ifndef ENAMETOOLONG 00034 #define ENAMETOOLONG 36 00035 #endif 00036 #ifndef EBADF 00037 #define EBADF 9 00038 #endif 00039 #ifndef EISDIR 00040 #define EISDIR 21 00041 #endif 00042 #ifndef ENOTEMPTY 00043 #define ENOTEMPTY 39 00044 #endif 00045 #ifndef ENOENT 00046 #define ENOENT 2 00047 #endif 00048 00049 00050 00051 #define PAL_FS_COPY_BUFFER_SIZE 256 //!< Size of the chunk to copy files 00052 PAL_PRIVATE const char *g_platOpenModeConvert[] = {"0", "r", "r+", "w+x", "w+"}; //!< platform convert table for \b fopen() modes 00053 PAL_PRIVATE const int g_platSeekWhenceConvert[] = {0, SEEK_SET, SEEK_CUR, SEEK_END}; //!< platform convert table for \b fseek() relative position modes 00054 00055 00056 00057 00058 00059 /*! \brief This function find the next file in a directory 00060 * 00061 * @param[in] *dh - Directory handler to an open DIR 00062 * @param[out] CurrentEntry - entry for the file found in Directory (pre allocated) 00063 * 00064 * \return true - upon successful operation.\n 00065 * 00066 */ 00067 PAL_PRIVATE bool pal_plat_findNextFile(DIR *dh, struct dirent ** CurrentEntry); 00068 00069 /*! \brief This function translate the platform errors opcode to pal error codes 00070 * 00071 * @param[in] errorOpCode - platform opcode to be translated 00072 * 00073 * \return PAL_SUCCESS upon successful operation.\n 00074 */ 00075 PAL_PRIVATE palStatus_t pal_plat_errorTranslation (int errorOpCode); 00076 00077 00078 /*! \brief This function build the full path name by adding the filename to the working path given in pathName arg 00079 * 00080 * @param[in] *pathName - pointer to the null-terminated string that specifies the directory name. 00081 * @param[in] *fileName - pointer to the file name 00082 * @param[out] *fullPath - pointer to the full path including the filename (pre allocated) 00083 * 00084 * \return PAL_SUCCESS upon successful operation.\n 00085 * PAL_FILE_SYSTEM_ERROR - see error code description \c palError_t 00086 * 00087 */ 00088 PAL_PRIVATE palStatus_t pal_plat_addFileNameToPath(const char *pathName, const char * fileName, char * fullPath); 00089 00090 /*! \brief This function copy one file from source folder to destination folder 00091 * 00092 * @param[in] pathNameSrc - Pointer to a null-terminated string that specifies the source dir. 00093 * @param[in] pathNameDest - Pointer to a null-terminated string that specifies the destination dir 00094 * @param[in] fileName - pointer the the file name 00095 * 00096 * \return PAL_SUCCESS upon successful operation.\n 00097 * PAL_FILE_SYSTEM_ERROR - see error code description \c palError_t 00098 * 00099 * \note File should not be open.\n 00100 * If the Destination file exist then it shall be truncated 00101 * 00102 */ 00103 PAL_PRIVATE palStatus_t pal_plat_fsCpFile(const char *pathNameSrc, char *pathNameDest, char * fileName); 00104 00105 palStatus_t pal_plat_fsMkdir(const char *pathName) 00106 { 00107 palStatus_t ret = PAL_SUCCESS; 00108 if(mkdir(pathName, 0600)) 00109 { 00110 ret = pal_plat_errorTranslation(errno); 00111 } 00112 return ret; 00113 } 00114 00115 00116 palStatus_t pal_plat_fsRmdir(const char *pathName) 00117 { 00118 palStatus_t ret = PAL_SUCCESS; 00119 00120 if (ret == PAL_SUCCESS) 00121 { 00122 if (remove(pathName)) 00123 { 00124 if(errno == EACCES) 00125 { 00126 ret = PAL_ERR_FS_DIR_NOT_EMPTY; 00127 } 00128 else if(errno == ENOENT) 00129 { 00130 ret = PAL_ERR_FS_NO_PATH; 00131 } 00132 else 00133 { 00134 ret = pal_plat_errorTranslation(errno); 00135 } 00136 } 00137 } 00138 return ret; 00139 } 00140 00141 00142 palStatus_t pal_plat_fsFopen(const char *pathName, pal_fsFileMode_t mode, palFileDescriptor_t *fd) 00143 { 00144 palStatus_t ret = PAL_SUCCESS; 00145 00146 if (mode == PAL_FS_FLAG_READWRITEEXCLUSIVE) 00147 { 00148 *fd = (palFileDescriptor_t)fopen(pathName, "r"); 00149 if (*fd) 00150 { 00151 ret = PAL_ERR_FS_NAME_ALREADY_EXIST; 00152 fclose((FILE *)*fd); 00153 } 00154 } 00155 00156 if(ret == PAL_SUCCESS) 00157 { 00158 *fd = (palFileDescriptor_t)fopen(pathName, g_platOpenModeConvert[mode]); 00159 if (!(*fd)) 00160 { 00161 ret = pal_plat_errorTranslation(errno); 00162 } 00163 } 00164 return ret; 00165 } 00166 00167 00168 palStatus_t pal_plat_fsFclose(palFileDescriptor_t *fd) 00169 { 00170 palStatus_t ret = PAL_SUCCESS; 00171 if (fclose((FILE *)*fd)) 00172 { 00173 ret = pal_plat_errorTranslation(errno); 00174 } 00175 return ret; 00176 } 00177 00178 00179 palStatus_t pal_plat_fsFread(palFileDescriptor_t *fd, void * buffer, size_t numOfBytes, size_t *numberOfBytesRead) 00180 { 00181 palStatus_t ret = PAL_SUCCESS; 00182 clearerr((FILE *)*fd); 00183 *numberOfBytesRead = fread(buffer, 1, numOfBytes, (FILE *)*fd); 00184 if (*numberOfBytesRead != numOfBytes) 00185 { 00186 if (ferror((FILE *)*fd)) 00187 { 00188 ret = PAL_ERR_FS_ERROR; 00189 } 00190 clearerr((FILE *)*fd); 00191 } 00192 return ret; 00193 } 00194 00195 00196 palStatus_t pal_plat_fsFwrite(palFileDescriptor_t *fd, const void *buffer, size_t numOfBytes, size_t *numberOfBytesWritten) 00197 { 00198 palStatus_t ret = PAL_SUCCESS; 00199 errno = 0; 00200 *numberOfBytesWritten = fwrite(buffer, 1, numOfBytes, (FILE *)*fd); 00201 if (*numberOfBytesWritten != numOfBytes) 00202 { 00203 if(errno == EBADF) 00204 { 00205 ret = PAL_ERR_FS_ACCESS_DENIED; 00206 } 00207 else 00208 { 00209 ret = pal_plat_errorTranslation(errno); 00210 } 00211 } 00212 return ret; 00213 } 00214 00215 00216 palStatus_t pal_plat_fsFseek(palFileDescriptor_t *fd, int32_t offset, pal_fsOffset_t whence) 00217 { 00218 palStatus_t ret = PAL_SUCCESS; 00219 if (fseek((FILE *)*fd, offset, g_platSeekWhenceConvert[whence])) 00220 { 00221 ret = pal_plat_errorTranslation(errno); 00222 } 00223 return ret; 00224 } 00225 00226 00227 palStatus_t pal_plat_fsFtell(palFileDescriptor_t *fd, int32_t * pos) 00228 { 00229 palStatus_t ret = PAL_SUCCESS; 00230 long retPos = 0; 00231 *pos = 0; 00232 retPos = ftell((FILE *)*fd); 00233 if (retPos < 0) 00234 { 00235 ret = pal_plat_errorTranslation(errno); 00236 } 00237 else 00238 { 00239 *pos = retPos; 00240 } 00241 return ret; 00242 } 00243 00244 00245 palStatus_t pal_plat_fsUnlink(const char *pathName) 00246 { 00247 palStatus_t ret = PAL_SUCCESS; 00248 if (remove(pathName)) 00249 { 00250 ret = pal_plat_errorTranslation(errno); 00251 } 00252 return ret; 00253 } 00254 00255 00256 palStatus_t pal_plat_fsRmFiles(const char *pathName) 00257 { 00258 DIR *dh = NULL; //Directory handler 00259 palStatus_t ret = PAL_SUCCESS; 00260 char buffer[PAL_MAX_FILE_AND_FOLDER_LENGTH] = {0}; //Buffer for coping the name and folder 00261 struct dirent * currentEntry = NULL; //file Entry 00262 00263 dh = opendir(pathName); 00264 if (dh) 00265 { 00266 while(true) 00267 { 00268 if (!pal_plat_findNextFile(dh, ¤tEntry)) 00269 { 00270 ret = PAL_ERR_FS_ERROR_IN_SEARCHING; 00271 break; 00272 } 00273 00274 if (currentEntry) 00275 { 00276 pal_plat_addFileNameToPath(pathName, currentEntry->d_name, buffer); 00277 if (currentEntry->d_type == DT_DIR) 00278 { 00279 pal_plat_fsRmFiles(buffer); 00280 } 00281 if (remove(buffer)) 00282 { 00283 ret = pal_plat_errorTranslation(errno); 00284 break; 00285 } 00286 } 00287 else 00288 {//End of directory reached without errors break, close directory and exit 00289 break; 00290 } 00291 }//while() 00292 } 00293 else//if (dh) 00294 { 00295 ret = PAL_ERR_FS_NO_PATH; 00296 } 00297 00298 if (dh) 00299 { 00300 closedir(dh); //Close DIR handler 00301 } 00302 return ret; 00303 } 00304 00305 00306 palStatus_t pal_plat_fsCpFolder(const char *pathNameSrc, char *pathNameDest) 00307 { 00308 DIR *src_dh = NULL; //Directory for the source Directory handler 00309 palStatus_t ret = PAL_SUCCESS; 00310 struct dirent * currentEntry = NULL; //file Entry 00311 00312 src_dh = opendir(pathNameSrc); 00313 if (src_dh == NULL) 00314 { 00315 ret = PAL_ERR_FS_NO_PATH; 00316 } 00317 00318 if (ret == PAL_SUCCESS) 00319 { 00320 while(true) 00321 { 00322 if (!pal_plat_findNextFile(src_dh, ¤tEntry)) 00323 { 00324 ret = PAL_ERR_FS_ERROR_IN_SEARCHING; 00325 break; 00326 } 00327 00328 if (currentEntry) 00329 { 00330 if (currentEntry->d_type == DT_DIR) 00331 { 00332 continue; 00333 } 00334 //copy the file to the destination 00335 ret = pal_plat_fsCpFile(pathNameSrc, pathNameDest, currentEntry->d_name); 00336 if (ret != PAL_SUCCESS) 00337 { 00338 break; 00339 } 00340 } 00341 else 00342 {//End of directory reached without errors break and close directory and exit 00343 break; 00344 } 00345 }//while() 00346 } 00347 00348 if (src_dh) 00349 { 00350 closedir(src_dh); 00351 } 00352 return ret; 00353 } 00354 00355 00356 PAL_PRIVATE palStatus_t pal_plat_fsCpFile(const char *pathNameSrc, char *pathNameDest, char * fileName) 00357 { 00358 palStatus_t ret = PAL_SUCCESS; 00359 palFileDescriptor_t src_fd = 0; 00360 palFileDescriptor_t dst_fd = 0; 00361 char buffer_name[PAL_MAX_FILE_AND_FOLDER_LENGTH] = {0}; //Buffer for coping the name and folder 00362 char * buffer = NULL; 00363 size_t bytesCount = 0; 00364 00365 //Add file name to path 00366 pal_plat_addFileNameToPath(pathNameSrc, fileName, buffer_name); 00367 src_fd = (palFileDescriptor_t)fopen(buffer_name, g_platOpenModeConvert[PAL_FS_FLAG_READONLY]); 00368 if (src_fd == 0) 00369 { 00370 ret = pal_plat_errorTranslation(errno); 00371 } 00372 else 00373 { 00374 //Add file name to path 00375 pal_plat_addFileNameToPath(pathNameDest, fileName, buffer_name); 00376 dst_fd = (palFileDescriptor_t)fopen(buffer_name, g_platOpenModeConvert[PAL_FS_FLAG_READWRITETRUNC]); 00377 if (dst_fd == 0) 00378 { 00379 ret = pal_plat_errorTranslation(errno); 00380 } 00381 else 00382 { 00383 buffer = (char*)malloc(PAL_FS_COPY_BUFFER_SIZE); 00384 if (!buffer) 00385 { 00386 ret = PAL_ERR_RTOS_RESOURCE ; 00387 } 00388 } 00389 } 00390 00391 if (ret == PAL_SUCCESS) 00392 { 00393 while (1) 00394 { 00395 ret = pal_fsFread(&src_fd, buffer, PAL_FS_COPY_BUFFER_SIZE, &bytesCount); 00396 if (ret != PAL_SUCCESS) 00397 { 00398 break; 00399 } 00400 00401 //Check if end of file reached 00402 if (bytesCount == 0) 00403 { 00404 break; 00405 } 00406 00407 ret = pal_fsFwrite(&dst_fd, buffer, bytesCount, &bytesCount); 00408 if (ret != PAL_SUCCESS) 00409 { 00410 break; 00411 } 00412 } 00413 } 00414 00415 if (src_fd != 0) 00416 { 00417 pal_fsFclose(&src_fd); 00418 } 00419 if (dst_fd != 0) 00420 { 00421 pal_fsFclose(&dst_fd); 00422 } 00423 if (buffer) 00424 { 00425 free(buffer); 00426 } 00427 return ret; 00428 } 00429 00430 00431 const char* pal_plat_fsGetDefaultRootFolder(pal_fsStorageID_t dataID) 00432 { 00433 const char* returnedRoot = NULL; 00434 if (PAL_FS_PARTITION_PRIMARY == dataID) 00435 { 00436 returnedRoot = PAL_FS_MOUNT_POINT_PRIMARY; 00437 } 00438 else if (PAL_FS_PARTITION_SECONDARY == dataID) 00439 { 00440 returnedRoot = PAL_FS_MOUNT_POINT_SECONDARY; 00441 } 00442 00443 return returnedRoot; 00444 } 00445 00446 00447 PAL_PRIVATE bool pal_plat_findNextFile(DIR *dh, struct dirent ** CurrentEntry) 00448 { 00449 bool ret = true; 00450 bool skip = false; 00451 bool foundFile = false; 00452 00453 do 00454 { 00455 errno = 0; 00456 *CurrentEntry = readdir(dh); 00457 if (*CurrentEntry) 00458 { 00459 /* Skip the names "." and ".." as we don't want to remove them. also make sure that the current entry point to REGULER file*/ 00460 skip = (!strcmp((*CurrentEntry)->d_name, ".")) || (!strcmp((*CurrentEntry)->d_name, "..")); 00461 if (skip) 00462 { 00463 continue; 00464 } 00465 else 00466 { 00467 foundFile = true; 00468 } 00469 } 00470 else 00471 {//Check if EOF reached 00472 if (errno) 00473 {//NOT!!! EOF other error 00474 ret = false; 00475 } 00476 break; //Break from while 00477 } 00478 } 00479 while((!foundFile) && (ret)); //While file has been found or ret is set to false 00480 00481 return ret; 00482 } 00483 00484 PAL_PRIVATE palStatus_t pal_plat_addFileNameToPath(const char *pathName, const char * fileName, char * fullPath) 00485 { 00486 palStatus_t ret = PAL_SUCCESS; 00487 00488 if ((strlen(pathName) >= PAL_MAX_FOLDER_DEPTH_CHAR) || (strlen(fileName) >= PAL_MAX_FULL_FILE_NAME)) 00489 { 00490 ret = PAL_ERR_FS_FILENAME_LENGTH; 00491 } 00492 else if (fullPath) 00493 { 00494 strcpy(fullPath, pathName); 00495 strcat(fullPath, "/"); 00496 strcat(fullPath, fileName); 00497 } 00498 else 00499 { 00500 ret = PAL_ERR_RTOS_RESOURCE ; 00501 } 00502 return ret; 00503 } 00504 00505 00506 00507 00508 PAL_PRIVATE palStatus_t pal_plat_errorTranslation (int errorOpCode) 00509 { 00510 palStatus_t ret = PAL_SUCCESS; 00511 00512 switch(errorOpCode) 00513 { 00514 case 0: 00515 break; 00516 case EACCES: 00517 case EFAULT: 00518 case EROFS: 00519 ret = PAL_ERR_FS_ACCESS_DENIED; 00520 break; 00521 00522 case EBUSY : 00523 ret = PAL_ERR_FS_BUSY; 00524 break; 00525 00526 case EEXIST: 00527 ret = PAL_ERR_FS_NAME_ALREADY_EXIST; 00528 break; 00529 00530 case ENAMETOOLONG: 00531 ret = PAL_ERR_FS_FILENAME_LENGTH; 00532 break; 00533 00534 case EBADF: 00535 ret = PAL_ERR_FS_BAD_FD; 00536 break; 00537 00538 case EINVAL: 00539 ret = PAL_ERR_FS_INVALID_ARGUMENT; 00540 break; 00541 00542 case EISDIR: 00543 ret = PAL_ERR_FS_FILE_IS_DIR; 00544 break; 00545 00546 case ENOTEMPTY: 00547 ret = PAL_ERR_FS_DIR_NOT_EMPTY; 00548 break; 00549 00550 case ENOENT: 00551 ret = PAL_ERR_FS_NO_FILE; 00552 break; 00553 00554 default: 00555 ret = PAL_ERR_FS_ERROR; 00556 break; 00557 } 00558 return ret; 00559 } 00560 00561 00562 size_t pal_plat_fsSizeCheck(const char *stringToChk) 00563 { 00564 size_t length = 0; 00565 length = strlen(stringToChk); 00566 return length; 00567 } 00568 00569 00570 00571 00572 00573 palStatus_t pal_plat_fsFormat(pal_fsStorageID_t dataID) 00574 { 00575 const char* partitionTranslationArray[] = 00576 { 00577 PAL_FS_MOUNT_POINT_PRIMARY, 00578 PAL_FS_MOUNT_POINT_SECONDARY 00579 };// "/sd\0" 00580 FileSystem *myFs; 00581 int err = 0; 00582 palStatus_t status = PAL_SUCCESS; 00583 FilePath myPath(partitionTranslationArray[dataID]); 00584 myFs = (FileSystem*)myPath.fileSystem(); 00585 if (NULL != myFs) 00586 { 00587 err = myFs->reformat(NULL); 00588 if (err < 0) 00589 { 00590 status = PAL_ERR_FS_ERROR; 00591 } 00592 } 00593 else //This should not happen 00594 { 00595 status = PAL_ERR_FS_ERROR; 00596 } 00597 return status; 00598 } 00599
Generated on Tue Jul 12 2022 16:22:09 by 1.7.2