Contiki 2.6
|
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 }