| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lwip_fs.c
Go to the documentation of this file.
1 /*
2 * @brief lwIP Filesystem implementation module
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
6 * All rights reserved.
7 *
8 * @par
9 * Software that is described herein is for illustrative purposes only
10 * which provides customers with programming information regarding the
11 * LPC products. This software is supplied "AS IS" without any warranties of
12 * any kind, and NXP Semiconductors and its licensor disclaim any and
13 * all warranties, express or implied, including all implied warranties of
14 * merchantability, fitness for a particular purpose and non-infringement of
15 * intellectual property rights. NXP Semiconductors assumes no responsibility
16 * or liability for the use of the software, conveys no license or rights under any
17 * patent, copyright, mask work right, or any other intellectual property rights in
18 * or to any products. NXP Semiconductors reserves the right to make changes
19 * in the software without notification. NXP Semiconductors also makes no
20 * representation or warranty that such application will be suitable for the
21 * specified use without further testing or modification.
22 *
23 * @par
24 * Permission to use, copy, modify, and distribute this software and its
25 * documentation is hereby granted, under NXP Semiconductors' and its
26 * licensor's relevant copyrights in the software, without fee, provided that it
27 * is used in conjunction with NXP Semiconductors microcontrollers. This
28 * copyright, permission, and disclaimer notice must appear in all copies of
29 * this code.
30 */
31
32 #include <stdio.h>
33 #include <string.h>
34 #include <stdlib.h>
35
36 #include "board.h"
37 #include "ff.h"
38 #include "fs_mem.h"
39 #include "lwip_fs.h"
40 #include "lpc43xx_dualcore_config.h"
41
42 #include "httpd_structs.h"
43
49 /*****************************************************************************
50 * Private types/enumerations/variables
51 ****************************************************************************/
52
53 /* Default html file */
54 const static char http_index_html[] =
55 "<html><head><title>Congrats!</title></head>"
56 "<body><h1>Welcome to our lwIP HTTP server!</h1>"
57 "<p>This is a small test page, served by httpd of "
58 "lwip.</p></body></html>";
59
60 static FATFS Fatfs; /* File system object */
61
62 /* Internal File descriptor structure */
63 struct file_ds {
64 uint8_t scratch[SECTOR_SZ];
65 FIL fi;
66 struct fs_file fs;
67 int fi_valid;
68 };
69
70 /*****************************************************************************
71 * Private functions
72 ****************************************************************************/
73
74 #ifdef OS_FREE_RTOS
75 #include "FreeRTOS.h"
76 #include "semphr.h"
77 static xSemaphoreHandle open_lock;
78 /* FreeRTOS mutex lock */
79 static int mutex_lock(xSemaphoreHandle *mx)
80 {
81 if (xSemaphoreTake(*mx, 500) != pdTRUE) {
82 return 1;
83 }
84 return 0;
85 }
86
87 /* FreeRTOS mutex unlock */
88 static void mutex_unlock(xSemaphoreHandle *mx)
89 {
90 xSemaphoreGive(*mx);
91 }
92
93 /* FreeRTOS mutex init */
94 static int mutex_init(void)
95 {
96 open_lock = xSemaphoreCreateMutex();
97 return open_lock == NULL;
98 }
99
100 #elif defined(OS_UCOS_III)
101
102 #include "os.h"
103 #include "cpu.h"
104 #include "os_cfg_app.h"
105
106 static OS_MUTEX *open_lock;
107
108 /* mutex lock function for ucos-iii */
109 static int mutex_lock(OS_MUTEX **mx)
110 {
111 CPU_TS ts;
112 OS_ERR os_err;
113 OSMutexPend(*mx, 500, OS_OPT_PEND_BLOCKING, &ts, &os_err);
114 if (os_err != OS_ERR_NONE) {
115 return 1;
116 }
117
118 return 0;
119 }
120
121 /* Mutex unlock function for ucos-iii */
122 static void mutex_unlock(OS_MUTEX **mx)
123 {
124 OS_ERR os_err;
125 OSMutexPost(*mx, OS_OPT_POST_NONE, &os_err);
126 }
127
128 /* Mutex init function for ucos-iii */
129 static int mutex_init(void)
130 {
131 static OS_MUTEX fsmutex;
132 OS_ERR os_err;
133 OSMutexCreate(&fsmutex, "DOS_FS_Mutex", &os_err);
134 if (os_err == OS_ERR_NONE) {
135 open_lock = &fsmutex;
136 return 0;
137 }
138 else {
139 return 1;
140 }
141 }
142
143 #else
144 static int open_lock;
145 /* Mutex lock function for standalone */
146 static int mutex_lock(int *mx)
147 {
148 return 0;
149 }
150
151 /* Mutex init for standalone */
152 static int mutex_init(void)
153 {
154 open_lock = 1;
155 return 0;
156 }
157
158 /* Mutex lock for standalone */
159 static void mutex_unlock(int *mx)
160 {}
161
162 #endif
163
168 static int
169 get_http_headers(const char *fName, char *buff)
170 {
171 unsigned int iLoop;
172 const char *pszExt = NULL;
173 const char *hdrs[4];
174
175 /* Ensure that we initialize the loop counter. */
176 iLoop = 0;
177
178 /* In all cases, the second header we send is the server identification
179 so set it here. */
180 hdrs[1] = g_psHTTPHeaderStrings[HTTP_HDR_SERVER];
181
182 /* Is this a normal file or the special case we use to send back the
183 default "404: Page not found" response? */
184 if (( fName == NULL) || ( *fName == 0) ) {
185 hdrs[0] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_FOUND];
186 hdrs[2] = g_psHTTPHeaderStrings[DEFAULT_404_HTML];
187 goto end_fn;
188 }
189 /* We are dealing with a particular filename. Look for one other
190 special case. We assume that any filename with "404" in it must be
191 indicative of a 404 server error whereas all other files require
192 the 200 OK header. */
193 if (strstr(fName, "404")) {
194 iLoop = HTTP_HDR_NOT_FOUND;
195 }
196 else if (strstr(fName, "400")) {
197 iLoop = HTTP_HDR_BAD_REQUEST;
198 }
199 else if (strstr(fName, "501")) {
200 iLoop = HTTP_HDR_NOT_IMPL;
201 }
202 else {
203 iLoop = HTTP_HDR_OK;
204 }
205 hdrs[0] = g_psHTTPHeaderStrings[iLoop];
206
207 /* Get a pointer to the file extension. We find this by looking for the
208 last occurrence of "." in the filename passed. */
209 pszExt = strrchr(fName, '.');
210
211 /* Does the FileName passed have any file extension? If not, we assume it
212 is a special-case URL used for control state notification and we do
213 not send any HTTP headers with the response. */
214 if (pszExt == NULL) {
215 return 0;
216 }
217
218 pszExt++;
219 /* Now determine the content type and add the relevant header for that. */
220 for (iLoop = 0; (iLoop < NUM_HTTP_HEADERS); iLoop++)
221 /* Have we found a matching extension? */
222 if (!strcmp(g_psHTTPHeaders[iLoop].extension, pszExt)) {
223 hdrs[2] =
224 g_psHTTPHeaderStrings[g_psHTTPHeaders[iLoop].headerIndex];
225 break;
226 }
227
228 /* Did we find a matching extension? */
229 if (iLoop == NUM_HTTP_HEADERS) {
230 /* No - use the default, plain text file type. */
231 hdrs[2] = g_psHTTPHeaderStrings[HTTP_HDR_DEFAULT_TYPE];
232 }
233
234 end_fn:
235 iLoop = strlen(hdrs[0]);
236 strcpy(buff, hdrs[0]);
237 strcat(buff, hdrs[1]);
238 strcat(buff, hdrs[2]);
239 return strlen(buff);
240 }
241
242 /*****************************************************************************
243 * Public functions
244 ****************************************************************************/
245
246 /* Read http header information into a string */
247 int GetHTTP_Header(const char *fName, char *buff)
248 {
249 return get_http_headers(fName, buff);
250 }
251
252 /* Opens the default index html file */
253 struct fs_file *fs_open_default(void) {
254 int hlen;
255
256 struct file_ds *fds;
257
258 struct fs_file *fs;
259
260 fds = malloc(sizeof(*fds));
261 if (fds == NULL) {
262 DEBUGSTR("Malloc Failure, Out of Memory!\r\n");
263 return NULL;
264 }
265 memset(fds, 0, sizeof(*fds));
266 fs = &fds->fs;
267 fs->pextension = (void *) fds; /* Store this for later use */
268 hlen = get_http_headers("default.htm", (char *) fds->scratch);
269 fs->data = (const char *) fds->scratch;
270 memcpy((void *) &fs->data[hlen], (void *) http_index_html, sizeof(http_index_html) - 1);
271 fs->len = hlen + sizeof(http_index_html) - 1;
272 fs->index = fs->len;
273 fs->http_header_included = 1;
274 return fs;
275 }
276
277 /* File open function */
278 struct fs_file *fs_open(const char *name) {
279 FRESULT res;
280 int hlen;
281 struct file_ds *fds;
282 struct fs_file *fs;
283
284 /* Too huge to keep in stack, must be protected with mutex */
285 static struct file_ds tmpds;
286
287 if (!open_lock)
288 f_mount(0, &Fatfs); /* Never fails */
289
290 /* Initialize the mutex if not done already */
291 if (!open_lock && mutex_init()) {
292 LWIP_DEBUGF(HTTPD_DEBUG, ("DFS: ERROR: Mutex Init!\r\n"));
293 return NULL;
294 }
295
296 if (mutex_lock(&open_lock)) {
297 LWIP_DEBUGF(HTTPD_DEBUG, ("DFS: ERROR: Mutex Timeout!\r\n"));
298 return NULL;
299 }
300 memset(&tmpds, 0, sizeof(tmpds));
301 fds = &tmpds;
302
303 res = f_open(&fds->fi, name, FA_READ);
304 if (res) {
305 LWIP_DEBUGF(HTTPD_DEBUG, ("DFS: OPEN: File %s does not exist\r\n", name));
306 mutex_unlock(&open_lock);
307 return NULL;
308 }
309
310 fds = malloc(sizeof(*fds));
311 if (fds == NULL) {
312 DEBUGSTR("Malloc Failure, Out of Memory!\r\n");
313 mutex_unlock(&open_lock);
314 return NULL;
315 }
316 memcpy(fds, &tmpds, sizeof(*fds));
317 mutex_unlock(&open_lock);
318
319 fs = &fds->fs;
320 fds->fi_valid = 1;
321 fs->pextension = (void *) fds; /* Store this for later use */
322 hlen = get_http_headers(name, (char *) fds->scratch);
323 fs->data = (const char *) fds->scratch;
324 fs->index = hlen;
325 fs->len = f_size(&fds->fi) + hlen;
326 fs->http_header_included = 1;
327 return fs;
328 }
329
330 /* File close function */
331 void fs_close(struct fs_file *file)
332 {
333 struct file_ds *fds;
334
335 if(file == NULL)
336 return;
337
338 fds = (struct file_ds *) file->pextension;
339 if (fds->fi_valid)
340 f_close(&fds->fi);
341 free(fds);
342 }
343
344 /* File read function */
345 int fs_read(struct fs_file *file, char *buffer, int count)
346 {
347 uint32_t i = 0;
348 struct file_ds *fds = (struct file_ds *) file->pextension;
349 if (f_read(&fds->fi, (uint8_t *) buffer, count, &i))
350 return 0; /* Error in reading file */
351 file->index += i;
352 return i;
353 }
354
355 /* Number of bytes left in the file */
356 int fs_bytes_left(struct fs_file *file)
357 {
358 return file->len - file->index;
359 }
360
361 /* Fat file system information function */
362 void FATFS_GetBufferInfo(uint8_t **buffer, uint32_t *size)
363 {
364 *buffer = (uint8_t *) RAMDISK_LOCATION;
365 *size = (uint32_t) RAMDISK_SIZE;
366 }
367
368 #ifdef LWIP_DEBUG
369 /* Assert print function */
370 void assert_printf(char *msg, int line, char *file)
371 {
372 DEBUGOUT("ASSERT: %s at %s:%d\r\n", msg, file, line);
373 }
374
375 /* LWIP str err function */
376 const char *lwip_strerr(err_t eno)
377 {
378 return "";
379 }
380
381 #endif
382