Contiki 2.5
cfs-sdcard.c
1 #include <efs-sdcard.h>
2 #include <sys/process.h>
3 #include <cfs/cfs.h>
4 #include <debug-uart.h>
5 
6 #include <stdio.h>
7 
8 
9 
10 process_event_t sdcard_inserted_event;
11 
12 process_event_t sdcard_removed_event;
13 
14 
15 
16 #define MAX_FDS 4
17 
18 static File file_descriptors[MAX_FDS];
19 
20 static int
21 find_free_fd()
22 {
23  int fd;
24  for (fd = 0; fd < MAX_FDS; fd++) {
25  if (!file_getAttr(&file_descriptors[fd], FILE_STATUS_OPEN)) {
26  return fd;
27  }
28  }
29  return -1;
30 }
31 
32 static File *
33 get_file(int fd)
34 {
35  if (!sdcard_ready()) return 0;
36  if (fd >= MAX_FDS || fd < 0) return NULL;
37  if (!file_getAttr(&file_descriptors[fd], FILE_STATUS_OPEN)) return NULL;
38  return &file_descriptors[fd];
39 }
40 
41 int
42 cfs_open (const char *name, int flags)
43 {
44  static int initialized = 0;
45  eint8 mode;
46  int fd;
47  if (!initialized) {
48  int fd;
49  /* Mark all file descriptors as free */
50  for (fd = 0; fd < MAX_FDS; fd++) {
51  file_setAttr(&file_descriptors[fd], FILE_STATUS_OPEN,0);
52  }
53  }
54  if (!sdcard_ready()) return -1;
55  fd = find_free_fd();
56  if (fd < 0) return -1;
57  if (flags == CFS_READ) {
58  mode = MODE_READ;
59  } else {
60  mode = MODE_APPEND;
61  }
62  if (file_fopen(&file_descriptors[fd], efs_sdcard_get_fs(),
63  (char*)name, mode) < 0) {
64  return -1;
65  }
66  return fd;
67 }
68 
69 void
70 cfs_close(int fd)
71 {
72  File *file = get_file(fd);
73  if (!file) return;
74  file_fclose(file);
75  fs_flushFs(efs_sdcard_get_fs());
76 }
77 
78 int
79 cfs_read (int fd, void *buf, unsigned int len)
80 {
81  File *file = get_file(fd);
82  if (!file) return 0;
83  return file_read(file, len, (euint8*)buf);
84 }
85 
86 int
87 cfs_write (int fd, const void *buf, unsigned int len)
88 {
89  File *file = get_file(fd);
90  if (!file) return 0;
91  return file_write(file, len, (euint8*)buf);
92 }
93 
94 cfs_offset_t
95 cfs_seek (int fd, cfs_offset_t offset, int whence)
96 {
97  File *file;
98  if (whence != CFS_SEEK_SET) return -1;
99  file = get_file(fd);
100  if (!file) return 0;
101  if (file_setpos(file, offset) != 0) return -1;
102  return file->FilePtr;
103 }
104 
105 
106 /* Cause a compile time error if expr is false */
107 #ifdef __GNUC__
108 #define COMPILE_TIME_CHECK(expr) \
109 (void) (__builtin_choose_expr ((expr), 0, ((void)0))+3)
110 #else
111 #define COMPILE_TIME_CHECK(expr)
112 #endif
113 
114 #define MAX_DIR_LISTS 4
115 DirList dir_lists[MAX_DIR_LISTS];
116 
117 static DirList *
118 find_free_dir_list()
119 {
120  unsigned int l;
121  for(l = 0; l < MAX_DIR_LISTS; l++) {
122  if (dir_lists[l].fs == NULL) {
123  return &dir_lists[l];
124  }
125  }
126  return NULL;
127 }
128 
129 int
130 cfs_opendir (struct cfs_dir *dirp, const char *name)
131 {
132  DirList *dirs;
133  COMPILE_TIME_CHECK(sizeof(DirList*) <= sizeof(struct cfs_dir));
134  if (!sdcard_ready()) return -1;
135  dirs = find_free_dir_list();
136  if (!dirs) return -1;
137  if (ls_openDir(dirs, efs_sdcard_get_fs(), (eint8*)name) != 0) {
138  dirs->fs = NULL;
139  return -1;
140  }
141  *(DirList**)dirp = dirs;
142  return 0;
143 }
144 
145 int
146 cfs_readdir (struct cfs_dir *dirp, struct cfs_dirent *dirent)
147 {
148  euint8 *start;
149  euint8 *end;
150  char *to = dirent->name;
151  DirList *dirs = *(DirList**)dirp;
152  if (!sdcard_ready()) return 1;
153  if (ls_getNext(dirs) != 0) return 1;
154  start = dirs->currentEntry.FileName;
155  end = start + 7;
156  while(end > start) {
157  if (*end > ' ') {
158  end++;
159  break;
160  }
161  end--;
162  }
163  while(start < end) {
164  *to++ = *start++;
165  }
166  start = dirs->currentEntry.FileName + 8;
167  end = start + 3;
168  if (*start > ' ') {
169  *to++ = '.';
170  *to++ = *start++;
171  while(start < end && *start > ' ') {
172  *to++ = *start++;
173  }
174  }
175  *to = '\0';
176  if (dirs->currentEntry.Attribute & ATTR_DIRECTORY) {
177  dirent->size = 0;
178  } else {
179  dirent->size = dirs->currentEntry.FileSize;
180  }
181  return 0;
182 }
183 
184 void
185 cfs_closedir (struct cfs_dir *dirp)
186 {
187  (*(DirList**)dirp)->fs = NULL;
188 }