httpd.c File Reference

#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


Function Documentation

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   ) 

Definition at line 251 of file httpd.c.

References pcb.

Referenced by ip_status_cb().

00252 {
00253     if (pcb)
00254         tcp_close(pcb);
00255 }

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 }


Variable Documentation

struct tcp_pcb* pcb = NULL

Definition at line 238 of file httpd.c.

Referenced by cmd_ping(), httpd_start(), and httpd_stop().


Generated on Fri Feb 19 02:24:08 2010 for AVR32 - H&D by  doxygen 1.5.5