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