Contiki 2.6

cfs-sdcard-arch.c

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