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
9process_event_t sdcard_inserted_event;
10
11process_event_t sdcard_removed_event;
12
13
14
15#define MAX_FDS 4
16
17static File file_descriptors[MAX_FDS];
18
19static int
20find_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
31static File *
32get_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
40int
41cfs_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
68void
69cfs_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
77int
78cfs_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
85int
86cfs_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
94cfs_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
114DirList dir_lists[MAX_DIR_LISTS];
115
116static DirList *
117find_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
128int
129cfs_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
144int
145cfs_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
183void
184cfs_closedir (struct cfs_dir *dirp)
185{
186 (*(DirList**)dirp)->fs = NULL;
187}
CFS header file.
#define CFS_READ
Specify that cfs_open() should open a file for reading.
Definition: cfs.h:95
int cfs_read(int fd, void *buf, unsigned int len)
Read data from an open file.
Definition: cfs-sdcard.c:78
int cfs_readdir(struct cfs_dir *dirp, struct cfs_dirent *dirent)
Read a directory entry.
Definition: cfs-sdcard.c:145
int cfs_open(const char *name, int flags)
Open a file.
Definition: cfs-sdcard.c:41
#define CFS_SEEK_SET
Specify that cfs_seek() should compute the offset from the beginning of the file.
Definition: cfs.h:132
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
void cfs_closedir(struct cfs_dir *dirp)
Close a directory opened with cfs_opendir().
Definition: cfs-sdcard.c:184
void cfs_close(int fd)
Close an open file.
Definition: cfs-sdcard.c:69
int cfs_offset_t
CFS directory entry name length.
Definition: cfs.h:65
int cfs_opendir(struct cfs_dir *dirp, const char *name)
Open a directory for reading directory entries.
Definition: cfs-sdcard.c:129
static void start(void)
Start measurement.
Header file for the Contiki process interface.