Contiki 2.6

cfs-sdcard.c

00001 #include <efs-sdcard.h>
00002 #include <sys/process.h>
00003 #include <cfs/cfs.h>
00004 #include <debug-uart.h>
00005 
00006 #include <stdio.h>
00007 
00008 
00009 
00010 process_event_t sdcard_inserted_event;
00011 
00012 process_event_t sdcard_removed_event;
00013 
00014 
00015 
00016 #define MAX_FDS 4
00017 
00018 static File file_descriptors[MAX_FDS];
00019 
00020 static int
00021 find_free_fd()
00022 {
00023   int fd;
00024   for (fd = 0; fd < MAX_FDS; fd++) {
00025     if (!file_getAttr(&file_descriptors[fd], FILE_STATUS_OPEN)) {
00026       return fd;
00027     }
00028   }
00029   return -1;
00030 }
00031 
00032 static File *
00033 get_file(int fd)
00034 {
00035   if (!sdcard_ready()) return 0;
00036   if (fd >= MAX_FDS || fd < 0) return NULL;
00037   if (!file_getAttr(&file_descriptors[fd], FILE_STATUS_OPEN)) return NULL;
00038   return &file_descriptors[fd];
00039 }
00040 
00041 int
00042 cfs_open (const char *name, int flags)
00043 {
00044   static int initialized = 0;
00045   eint8 mode;
00046   int fd;
00047   if (!initialized) {
00048     int fd;
00049     /* Mark all file descriptors as free */
00050     for (fd = 0; fd < MAX_FDS; fd++) {
00051       file_setAttr(&file_descriptors[fd], FILE_STATUS_OPEN,0);
00052     }
00053   }
00054   if (!sdcard_ready()) return -1;
00055   fd = find_free_fd();
00056   if (fd < 0) return -1;
00057   if (flags == CFS_READ) {
00058     mode = MODE_READ;
00059   } else {
00060     mode = MODE_APPEND;
00061   }
00062   if (file_fopen(&file_descriptors[fd], efs_sdcard_get_fs(),
00063                  (char*)name, mode) < 0) {
00064     return -1;
00065   }
00066   return fd;
00067 }
00068 
00069 void
00070 cfs_close(int fd)
00071 {
00072   File *file = get_file(fd);
00073   if (!file) return;
00074   file_fclose(file);
00075   fs_flushFs(efs_sdcard_get_fs());
00076 }
00077 
00078 int
00079 cfs_read (int fd, void *buf, unsigned int len)
00080 {
00081   File *file = get_file(fd);
00082   if (!file) return 0;
00083   return file_read(file, len, (euint8*)buf);
00084 }
00085 
00086 int
00087 cfs_write (int fd, const void *buf, unsigned int len)
00088 {
00089   File *file = get_file(fd);
00090   if (!file) return 0;
00091   return file_write(file, len, (euint8*)buf);
00092 }
00093 
00094 cfs_offset_t
00095 cfs_seek (int fd, cfs_offset_t offset, int whence)
00096 {
00097   File *file;
00098   if (whence != CFS_SEEK_SET) return -1;
00099   file = get_file(fd);
00100   if (!file) return 0;
00101   if (file_setpos(file, offset) != 0) return -1;
00102   return file->FilePtr;
00103 }
00104 
00105 
00106 /* Cause a compile time error if expr is false */
00107 #ifdef __GNUC__
00108 #define COMPILE_TIME_CHECK(expr) \
00109 (void) (__builtin_choose_expr ((expr), 0, ((void)0))+3)
00110 #else
00111 #define COMPILE_TIME_CHECK(expr)
00112 #endif
00113 
00114 #define MAX_DIR_LISTS 4
00115 DirList dir_lists[MAX_DIR_LISTS];
00116 
00117 static DirList *
00118 find_free_dir_list()
00119 {
00120   unsigned int l;
00121   for(l = 0; l < MAX_DIR_LISTS; l++) {
00122     if (dir_lists[l].fs == NULL) {
00123       return &dir_lists[l];
00124     }
00125   }
00126   return NULL;
00127 }
00128 
00129 int
00130 cfs_opendir (struct cfs_dir *dirp, const char *name)
00131 {
00132   DirList *dirs;
00133   COMPILE_TIME_CHECK(sizeof(DirList*) <= sizeof(struct cfs_dir));
00134   if (!sdcard_ready()) return -1;
00135   dirs = find_free_dir_list();
00136   if (!dirs) return -1;
00137   if (ls_openDir(dirs, efs_sdcard_get_fs(), (eint8*)name) != 0) {
00138     dirs->fs = NULL;
00139     return -1;
00140   }
00141   *(DirList**)dirp = dirs;
00142   return 0;
00143 }
00144 
00145 int
00146 cfs_readdir (struct cfs_dir *dirp, struct cfs_dirent *dirent)
00147 {
00148   euint8 *start;
00149   euint8 *end;
00150   char *to = dirent->name;
00151   DirList *dirs = *(DirList**)dirp;
00152   if (!sdcard_ready()) return 1;
00153   if (ls_getNext(dirs) != 0) return 1;
00154   start = dirs->currentEntry.FileName;
00155   end = start + 7;
00156   while(end > start) {
00157     if (*end > ' ') {
00158       end++;
00159       break;
00160     }
00161     end--;
00162   }
00163   while(start < end) {
00164     *to++ = *start++;
00165   }
00166   start = dirs->currentEntry.FileName + 8;
00167   end = start + 3;
00168   if (*start > ' ') {
00169     *to++ = '.';
00170     *to++ = *start++;
00171     while(start < end && *start > ' ') {
00172       *to++ = *start++;
00173     }
00174   }
00175   *to = '\0';
00176   if (dirs->currentEntry.Attribute & ATTR_DIRECTORY) {
00177     dirent->size = 0;
00178   } else {
00179     dirent->size = dirs->currentEntry.FileSize;
00180   }
00181   return 0;
00182 }
00183 
00184 void
00185 cfs_closedir (struct cfs_dir *dirp)
00186 {
00187   (*(DirList**)dirp)->fs = NULL;
00188 }