| 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
netconn_fs.c
Go to the documentation of this file.
1 /*
2 * @brief Netconn implementation that gets data from filesystem
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 "lwip/opt.h"
35 #include "lwip/arch.h"
36 #include "lwip/api.h"
37 #include "../webserver/lwip_fs.h"
38
39 #include "lpc43xx_dualcore_config.h"
40 #include "ipc_example.h"
41
42 #if LWIP_NETCONN
43
44 #ifndef HTTPD_DEBUG
45 #define HTTPD_DEBUG LWIP_DBG_OFF
46 #endif
47
48 // FIXME - needs standards formatting
49
50 /* Default file content incase a valid filesystem is not present */
51 const static char http_html_hdr[] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n";
52 const static char http_index_html[] = "<html><head><title>Congrats!</title></head><body><h1>Welcome to our lwIP HTTP server!</h1><p>This is a small test page, served by httpserver-netconn.</body></html>";
53
54 /* Dynamic header generation based on Filename */
55 extern int GetHTTP_Header(const char *fName, char *buff);
56 void http_server_netconn_init(void);
57
58 #ifndef CRLF
59 #define CRLF "\r\n"
60 #endif
61
62 /* Function to check if the requested method is supported */
63 static int supported_method(const char *method)
64 {
65 if (strncmp(method, "GET", 3) == 0)
66 return 1;
67 if (strncmp(method, "POST", 4) == 0)
68 return 1;
69 return 0;
70 }
71
72 /* Function to extract version information from URI */
73 static uint32_t get_version(const char *vstr)
74 {
75 int major = 0, minor = 0;
76 sscanf(vstr, "HTTP/%d.%d", &major, &minor);
77 return (major << 16) | minor;
78 }
79
81 static void
82 http_server_netconn_serve(struct netconn *conn)
83 {
84 struct netbuf *inbuf;
85 char *buf, *tbuf;
86 u16_t buflen;
87 struct fs_file *fs = NULL;
88 err_t err;
89 static uint8_t file_buffer[1024];
90 int len;
91 uint32_t req_ver;
92
93 /* Read the data from the port, blocking if nothing yet there.
94 We assume the request (the part we care about) is in one netbuf */
95 err = netconn_recv(conn, &inbuf);
96
97 if (err != ERR_OK) return;
98
99 netbuf_data(inbuf, (void**)&buf, &buflen);
100 if (buflen < 5 || strstr(buf, CRLF) == NULL) {
101 LWIP_DEBUGF(HTTPD_DEBUG, ("HTTPD: Invalid Request Line\r\n"));
102 goto close_and_exit;
103 }
104
105 LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("HTTPD: Got URI %s\r\n", buf));
106
107 tbuf = strchr(buf, ' ');
108 if (tbuf == NULL) {
109 LWIP_DEBUGF(HTTPD_DEBUG, ("HTTPD: Parse error in Request Line\r\n"));
110 goto close_and_exit;
111 }
112
113 *tbuf++ = 0;
114 if (!supported_method(buf)) {
115 LWIP_DEBUGF(HTTPD_DEBUG, ("HTTPD: Un-supported method: %s\r\n", buf));
116 goto close_and_exit;
117 }
118 buf = tbuf;
119 tbuf = strchr(buf, ' ');
120 if (tbuf == NULL) {
121 LWIP_DEBUGF(HTTPD_DEBUG, ("HTTPD: Version string not found: %s\r\n", buf));
122 } else {
123 *tbuf++ = 0;
124 req_ver = get_version(tbuf);
125 LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("HTTPD: Request version %d.%d\r\n",
126 req_ver >> 16, req_ver & 0xFFFF));
127 }
128
129 tbuf = strchr(buf, '?');
130 if (tbuf != NULL) {
131 LWIP_DEBUGF(HTTPD_DEBUG, ("HTTPD: Arguements %s in URI ignored\r\n", tbuf));
132 *tbuf++ = 0;
133 }
134 if (strlen(buf) == 1 && *buf == '/') {
135 fs = fs_open("/index.htm");
136 if (fs == NULL)
137 fs = fs_open("/index.html");
138 if (fs == NULL) {
139 /* No home page, send if from buffer */
140 netconn_write(conn, http_html_hdr, sizeof(http_html_hdr)-1, NETCONN_NOCOPY);
141 netconn_write(conn, http_index_html, sizeof(http_index_html)-1, NETCONN_NOCOPY);
142 goto close_and_exit;
143 }
144 } else {
145 fs = fs_open(buf);
146 }
147 if (fs == NULL) {
148 int len;
149 LWIP_DEBUGF(HTTPD_DEBUG, ("HTTPD: Unable to open file[%s]\r\n", buf));
150 len = GetHTTP_Header(NULL, (char *)file_buffer);
151 netconn_write(conn, file_buffer, len, NETCONN_NOCOPY);
152 goto close_and_exit;
153 }
154
155 /***
156 * FIXME: There is a possible race condition while accessing
157 * file_buffer, must use a mutex to protect it.
158 **/
159 if (fs->http_header_included)
160 /* Send the header */
161 netconn_write(conn, fs->data, fs->index, NETCONN_NOCOPY);
162
163 /* Read the file now */
164 while ((len = fs_read(fs, (char *)file_buffer, sizeof(file_buffer))) > 0) {
165 netconn_write(conn, file_buffer, len, NETCONN_NOCOPY);
166 }
167
168 close_and_exit:
169 fs_close(fs);
170 /* Close the connection (server closes in HTTP) */
171 netconn_close(conn);
172
173 /* Delete the buffer (netconn_recv gives us ownership,
174 so we have to make sure to deallocate the buffer) */
175 netbuf_delete(inbuf);
176 }
177
179 static void
180 http_server_netconn_thread(void *arg)
181 {
182 struct netconn *conn, *newconn;
183 err_t err;
184 LWIP_UNUSED_ARG(arg);
185
186 /* Create a new TCP connection handle */
187 conn = netconn_new(NETCONN_TCP);
188 LWIP_ERROR("http_server: invalid conn", (conn != NULL), return;);
189
190 /* Bind to port 80 (HTTP) with default IP address */
191 netconn_bind(conn, NULL, 80);
192
193 /* Put the connection into LISTEN state */
194 netconn_listen(conn);
195
196 do {
197 err = netconn_accept(conn, &newconn);
198 if (err == ERR_OK) {
199 /* Push the remote IP info to other Core */
200 ip_addr_t remote_ip;
201 u16_t port_num;
202 err = netconn_getaddr(newconn, &remote_ip, &port_num, 0);
203 if(err == ERR_OK) {
204 extern void EVENT_lwip_http_access(uint32_t);
205 EVENT_lwip_http_access(remote_ip.addr);
206 }
207
208 http_server_netconn_serve(newconn);
209 netconn_delete(newconn);
210 }
211 } while(err == ERR_OK);
212 LWIP_DEBUGF(HTTPD_DEBUG,
213 ("http_server_netconn_thread: netconn_accept received error %d, shutting down",
214 err));
215 netconn_close(conn);
216 netconn_delete(conn);
217 }
218
219 /*********************************************************************/
227 void
228 http_server_netconn_init(void)
229 {
230 sys_thread_new("http_server_netconn", http_server_netconn_thread, NULL, DEFAULT_THREAD_STACKSIZE + 128, DEFAULT_THREAD_PRIO);
231 }
232
233 #ifdef __IAR_SYSTEMS_ICC__
234 WEAK_SYMBOL
235 #else
236 WEAK_SYMBOL void EVENT_lwip_http_access(uint32_t addr);
237 #endif
238
246 void EVENT_lwip_http_access(uint32_t addr)
247 {
248 /* Push the remote IP address to other core */
249 ipcex_msgPush(IPCEX_ID_LWIP, addr);
250 }
251
252 #endif /* LWIP_NETCONN*/