Mbed Cloud example program for workshop in W27 2018.

Dependencies:   MMA7660 LM75B

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_plat_fileSystem.cpp Source File

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, &currentEntry))
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, &currentEntry))
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