LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 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 
247 {
248  /* Push the remote IP address to other core */
250 }
251 
252 #endif /* LWIP_NETCONN*/