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