#include "lwip/debug.h"
#include "lwip/stats.h"
#include "httpd.h"
#include "lwip/tcp.h"
#include "fs.h"
#include "printf-stdarg.h"
Go to the source code of this file.
Data Structures | |
struct | http_state |
Functions | |
static void | close_conn (struct tcp_pcb *pcb, struct http_state *hs) |
static void | conn_err (void *arg, err_t err) |
static err_t | http_accept (void *arg, struct tcp_pcb *pcb, err_t err) |
static err_t | http_poll (void *arg, struct tcp_pcb *pcb) |
static err_t | http_recv (void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) |
static err_t | http_sent (void *arg, struct tcp_pcb *pcb, u16_t len) |
err_t | httpd_start (void) |
void | httpd_stop (void) |
static void | send_data (struct tcp_pcb *pcb, struct http_state *hs) |
Variables | |
struct tcp_pcb * | pcb = NULL |
static void close_conn | ( | struct tcp_pcb * | pcb, | |
struct http_state * | hs | |||
) | [static] |
Definition at line 63 of file httpd.c.
Referenced by http_recv(), and http_sent().
00064 { 00065 tcp_arg(pcb, NULL); 00066 tcp_sent(pcb, NULL); 00067 tcp_recv(pcb, NULL); 00068 mem_free(hs); 00069 tcp_close(pcb); 00070 }
static void conn_err | ( | void * | arg, | |
err_t | err | |||
) | [static] |
Definition at line 52 of file httpd.c.
Referenced by http_accept().
00053 { 00054 struct http_state *hs; 00055 00056 LWIP_UNUSED_ARG(err); 00057 00058 hs = arg; 00059 mem_free(hs); 00060 }
static err_t http_accept | ( | void * | arg, | |
struct tcp_pcb * | pcb, | |||
err_t | err | |||
) | [static] |
Definition at line 201 of file httpd.c.
References conn_err(), http_state::file, http_poll(), http_recv(), http_state::left, printk(), and http_state::retries.
Referenced by httpd_start().
00202 { 00203 struct http_state *hs; 00204 00205 LWIP_UNUSED_ARG(arg); 00206 LWIP_UNUSED_ARG(err); 00207 00208 tcp_setprio(pcb, TCP_PRIO_MIN); 00209 00210 /* Allocate memory for the structure that holds the state of the 00211 connection. */ 00212 hs = (struct http_state *)mem_malloc(sizeof(struct http_state)); 00213 00214 if (hs == NULL) { 00215 printk("http_accept: Out of memory\n"); 00216 return ERR_MEM; 00217 } 00218 00219 /* Initialize the structure. */ 00220 hs->file = NULL; 00221 hs->left = 0; 00222 hs->retries = 0; 00223 00224 /* Tell TCP that this is the structure we wish to be passed for our 00225 callbacks. */ 00226 tcp_arg(pcb, hs); 00227 00228 /* Tell TCP that we wish to be informed of incoming data by a call 00229 to the http_recv() function. */ 00230 tcp_recv(pcb, http_recv); 00231 00232 tcp_err(pcb, conn_err); 00233 00234 tcp_poll(pcb, http_poll, 4); 00235 return ERR_OK; 00236 }
static err_t http_poll | ( | void * | arg, | |
struct tcp_pcb * | pcb | |||
) | [static] |
Definition at line 100 of file httpd.c.
References http_state::retries, and send_data().
Referenced by http_accept().
00101 { 00102 struct http_state *hs; 00103 00104 hs = arg; 00105 00106 if (hs == NULL) { 00107 tcp_abort(pcb); 00108 return ERR_ABRT; 00109 } else { 00110 ++hs->retries; 00111 if (hs->retries == 4) { 00112 tcp_abort(pcb); 00113 return ERR_ABRT; 00114 } 00115 send_data(pcb, hs); 00116 } 00117 00118 return ERR_OK; 00119 }
static err_t http_recv | ( | void * | arg, | |
struct tcp_pcb * | pcb, | |||
struct pbuf * | p, | |||
err_t | err | |||
) | [static] |
Definition at line 142 of file httpd.c.
References close_conn(), fs_file::data, data, http_state::file, fs_open(), http_sent(), http_state::left, fs_file::len, printk(), and send_data().
Referenced by http_accept().
00143 { 00144 int i; 00145 char *data; 00146 struct fs_file file; 00147 struct http_state *hs; 00148 hs = arg; 00149 00150 if (err == ERR_OK && p != NULL) { 00151 00152 /* Inform TCP that we have taken the data. */ 00153 tcp_recved(pcb, p->tot_len); 00154 00155 if (hs->file == NULL) { 00156 data = p->payload; 00157 00158 if (strncmp(data, "GET ", 4) == 0) { 00159 for(i = 0; i < 40; i++) { 00160 if (((char *)data + 4)[i] == ' ' || 00161 ((char *)data + 4)[i] == '\r' || 00162 ((char *)data + 4)[i] == '\n') { 00163 ((char *)data + 4)[i] = 0; 00164 } 00165 } 00166 00167 if (*(char *)(data + 4) == '/' && 00168 *(char *)(data + 5) == 0) { 00169 fs_open("/index.html", &file); 00170 } else if (!fs_open((char *)data + 4, &file)) { 00171 fs_open("/404.html", &file); 00172 } 00173 00174 hs->file = file.data; 00175 hs->left = file.len; 00176 00177 pbuf_free(p); 00178 send_data(pcb, hs); 00179 00180 /* Tell TCP that we wish be to informed of data that has been 00181 successfully sent by a call to the http_sent() function. */ 00182 tcp_sent(pcb, http_sent); 00183 } 00184 else { 00185 printk("%s\n", p->payload); 00186 pbuf_free(p); 00187 close_conn(pcb, hs); 00188 } 00189 } else { 00190 pbuf_free(p); 00191 } 00192 } 00193 00194 if (err == ERR_OK && p == NULL) { 00195 close_conn(pcb, hs); 00196 } 00197 return ERR_OK; 00198 }
static err_t http_sent | ( | void * | arg, | |
struct tcp_pcb * | pcb, | |||
u16_t | len | |||
) | [static] |
Definition at line 122 of file httpd.c.
References close_conn(), http_state::left, http_state::retries, and send_data().
Referenced by http_recv().
00123 { 00124 struct http_state *hs; 00125 00126 LWIP_UNUSED_ARG(len); 00127 00128 hs = arg; 00129 00130 hs->retries = 0; 00131 00132 if (hs->left > 0) { 00133 send_data(pcb, hs); 00134 } else { 00135 close_conn(pcb, hs); 00136 } 00137 00138 return ERR_OK; 00139 }
err_t httpd_start | ( | void | ) |
Definition at line 240 of file httpd.c.
References http_accept(), and pcb.
Referenced by ip_status_cb().
00241 { 00242 pcb = tcp_new(); 00243 if (pcb == NULL) 00244 return ERR_MEM; 00245 tcp_bind(pcb, IP_ADDR_ANY, 80); 00246 pcb = tcp_listen(pcb); 00247 tcp_accept(pcb, http_accept); 00248 return ERR_OK; 00249 }
void httpd_stop | ( | void | ) |
static void send_data | ( | struct tcp_pcb * | pcb, | |
struct http_state * | hs | |||
) | [static] |
Definition at line 73 of file httpd.c.
References http_state::file, and http_state::left.
Referenced by http_poll(), http_recv(), and http_sent().
00074 { 00075 err_t err; 00076 u16_t len; 00077 00078 /* We cannot send more data than space available in the send 00079 buffer. */ 00080 if (tcp_sndbuf(pcb) < hs->left) { 00081 len = tcp_sndbuf(pcb); 00082 } else { 00083 len = hs->left; 00084 } 00085 00086 do { 00087 err = tcp_write(pcb, hs->file, len, 0); 00088 if (err == ERR_MEM) { 00089 len /= 2; 00090 } 00091 } while (err == ERR_MEM && len > 1); 00092 00093 if (err == ERR_OK) { 00094 hs->file += len; 00095 hs->left -= len; 00096 } 00097 }
struct tcp_pcb* pcb = NULL |