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