/*
 * Copyright (c) 2001, Adam Dunkels.
 * All rights reserved. 
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions 
 * are met: 
 * 1. Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above copyright 
 *    notice, this list of conditions and the following disclaimer in the 
 *    documentation and/or other materials provided with the distribution. 
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Adam Dunkels.
 * 4. The name of the author may not be used to endorse or promote
 *    products derived from this software without specific prior
 *    written permission.  
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 *
 * This file is part of the uIP TCP/IP stack.
 *
 * $Id: httpd.c,v 1.3 2004/08/09 22:25:06 adamdunkels Exp $
 *
 */


#include "contiki.h"
#include "httpd.h"
#include "httpd-fs.h"
#include "httpd-fsdata.h"
#include "httpd-cgi.h"

#include "webserver.h"

#include <avr/pgmspace.h>

/* The HTTP server states: */
#define HTTP_DEALLOCATED  0
#define HTTP_NOGET        1
#define HTTP_FILE         2
#define HTTP_TEXT         3
#define HTTP_FUNC         4
#define HTTP_END          5

#ifdef DEBUG
#include <stdio.h>
#define PRINT(x) printf("%s", x)
#define PRINTLN(x) printf("%s\n", x)
#else /* DEBUG */
#define PRINT(x)
#define PRINTLN(x)
#endif /* DEBUG */

struct httpd_state *hs;

extern const struct httpd_fsdata_file file_index_html;
extern const struct httpd_fsdata_file file_404_html;

static void next_scriptline(void);
static void next_scriptstate(void);

#define ISO_G        0x47
#define ISO_E        0x45
#define ISO_T        0x54
#define ISO_slash    0x2f    
#define ISO_c        0x63
#define ISO_g        0x67
#define ISO_i        0x69
#define ISO_space    0x20
#define ISO_nl       0x0a
#define ISO_cr       0x0d
#define ISO_a        0x61
#define ISO_t        0x74
#define ISO_hash     0x23
#define ISO_period   0x2e

#define HTTPD_CONF_NUMCONNS UIP_CONNS
static struct httpd_state conns[HTTPD_CONF_NUMCONNS];
static u8_t i;

static char tmp[40];
/*-----------------------------------------------------------------------------------*/
static struct httpd_state *
alloc_state(void)
{
  
  for(i = 0; i < HTTPD_CONF_NUMCONNS; ++i) {
    if(conns[i].state == HTTP_DEALLOCATED) {
      return &conns[i];
    }
  }

  /* We are overloaded! XXX: we'll just kick all other connections! */
  for(i = 0; i < HTTPD_CONF_NUMCONNS; ++i) {
    conns[i].state = HTTP_DEALLOCATED;
  }
  
  return NULL;
}
/*-----------------------------------------------------------------------------------*/
static void
dealloc_state(struct httpd_state *s)
{
  s->state = HTTP_DEALLOCATED;
}
/*-----------------------------------------------------------------------------------*/
void
httpd_init(void)
{
  httpd_fs_init();
  
  /* Listen to port 80. */
  tcp_listen(HTONS(80));

  for(i = 0; i < HTTPD_CONF_NUMCONNS; ++i) {
    conns[i].state = HTTP_DEALLOCATED;
  }
}
/*-----------------------------------------------------------------------------------*/
void
httpd_appcall(void *state)
{
  struct httpd_fs_file fsfile;  
  u8_t i;
  char c;

  hs = (struct httpd_state *)(state);
  
  /* We use the uip_ test functions to deduce why we were
     called. If uip_connected() is non-zero, we were called
     because a remote host has connected to us. If
     uip_newdata() is non-zero, we were called because the
     remote host has sent us new data, and if uip_acked() is
     non-zero, the remote host has acknowledged the data we
     previously sent to it. */
  if(uip_connected()) {

    /* Since we've just been connected, the state pointer should be
       NULL and we need to allocate a new state object. If we have run
       out of memory for state objects, we'll have to abort the
       connection and return. */
    if(hs == NULL) {
      hs = alloc_state();
      if(hs == NULL) {
	uip_close();
	return;
      }
      tcp_markconn(uip_conn, (void *)hs);
    }
    /* Since we have just been connected with the remote host, we
       reset the state for this connection. The ->count variable
       contains the amount of data that is yet to be sent to the
       remote host, and the ->state is set to HTTP_NOGET to signal
       that we haven't received any HTTP GET request for this
       connection yet. */
    hs->state = HTTP_NOGET;
    hs->count = 0;
    hs->poll = 0;
  } else if(uip_closed() || uip_aborted()) {
    if(hs != NULL) {
      dealloc_state(hs);
    }
    return;
  } else if(uip_poll()) {
    /* If we are polled ten times, we abort the connection. This is
       because we don't want connections lingering indefinately in
       the system. */
    if(hs != NULL) {
      if(hs->state == HTTP_DEALLOCATED) {
	uip_abort();
      } else if(hs->poll++ >= 100) {
	uip_abort();
	dealloc_state(hs);
      }
    }
    return;
  }


  if(uip_newdata() && hs->state == HTTP_NOGET) {
    hs->poll = 0;
    /* This is the first data we receive, and it should contain a
       GET. */
      
    /* Check for GET. */
    if(uip_appdata[0] != ISO_G ||
       uip_appdata[1] != ISO_E ||
       uip_appdata[2] != ISO_T ||
       uip_appdata[3] != ISO_space) {
      /* If it isn't a GET, we abort the connection. */
      uip_abort();
      dealloc_state(hs);
      return;
    }
	       
    /* Find the file we are looking for. */
    for(i = 4; i < 40; ++i) {
      if(uip_appdata[i] == ISO_space ||
	 uip_appdata[i] == ISO_cr ||
	 uip_appdata[i] == ISO_nl) {
	uip_appdata[i] = 0;
	break;
      }
    }

    PRINT("request for file ");
    PRINTLN(&uip_appdata[4]);
    webserver_log_file(uip_conn->ripaddr, &uip_appdata[4]);
    /* Check for a request for "/". */
    if(uip_appdata[4] == ISO_slash &&
       uip_appdata[5] == 0) {
      memcpy_P(tmp, file_index_html.name, sizeof(tmp));
      httpd_fs_open((const char *)tmp, &fsfile);  
    } else {
      if(!httpd_fs_open((const char *)&uip_appdata[4], &fsfile)) {
	PRINTLN("couldn't open file");
	memcpy_P(tmp, file_404_html.name, sizeof(tmp));
	httpd_fs_open((const char *)tmp, &fsfile);  
      }
    } 
    httpd_fs_inc();
    
    if(uip_appdata[4] == ISO_slash &&
       uip_appdata[5] == ISO_c &&
       uip_appdata[6] == ISO_g &&
       uip_appdata[7] == ISO_i &&
       uip_appdata[8] == ISO_slash) {
      /* If the request is for a file that starts with "/cgi/", we
	 prepare for invoking a script. */	
      hs->script = fsfile.data;
      next_scriptstate();
    } else {
      hs->script = NULL;
      /* The web server is now no longer in the HTTP_NOGET state, but
	 in the HTTP_FILE state since is has now got the GET from
	 the client and will start transmitting the file. */
      hs->state = HTTP_FILE;

      /* Point the file pointers in the connection state to point to
	 the first byte of the file. */
      hs->dataptr = fsfile.data;
      hs->count = fsfile.len;	
    }     
  }

    
  if(hs->state != HTTP_FUNC) {
    /* Check if the client (remote end) has acknowledged any data that
       we've previously sent. If so, we move the file pointer further
       into the file and send back more data. If we are out of data to
       send, we close the connection. */
    if(uip_acked()) {
      hs->poll = 0;	
      if(hs->count >= uip_mss()) {
	hs->count -= uip_mss();
	hs->dataptr += uip_mss();
      } else {
	hs->count = 0;
      }
	
      if(hs->count == 0) {
	if(hs->script != NULL) {
	  next_scriptline();
	  next_scriptstate();
	} else {
	  uip_close();
	  dealloc_state(hs);
	}
      }
    }         
  }
    
  if(hs->state == HTTP_FUNC) {
    /* Call the CGI function. */
    memcpy_P(&c, &hs->script[2], 1);
    if(httpd_cgitab[c - ISO_a]()) {
      /* If the function returns non-zero, we jump to the next line
	 in the script. */
      next_scriptline();
      next_scriptstate();
    }
  }

  if(hs->state != HTTP_FUNC && !uip_poll()) {
    hs->poll = 0;
    /* Send a piece of data, but not more than the MSS of the
       connection. */
    memcpy_P(uip_appdata, hs->dataptr, uip_mss());
    uip_send(uip_appdata,
	     hs->count > uip_mss()? uip_mss(): hs->count);
  }

  /* Finally, return to uIP. Our outgoing packet will soon be on its
     way... */
}
/*-----------------------------------------------------------------------------------*/
/* next_scriptline():
 *
 * Reads the script until it finds a newline. */
static void
next_scriptline(void)
{
  char c;
  /* Loop until we find a newline character. */
  do {
    ++(hs->script);
    memcpy_P(&c, hs->script, 1);
  } while(c != ISO_nl);

  /* Eat up the newline as well. */
  ++(hs->script);
}
/*-----------------------------------------------------------------------------------*/
/* next_sciptstate:
 *
 * Reads one line of script and decides what to do next.
 */
static void
next_scriptstate(void)
{
  struct httpd_fs_file fsfile;
  u8_t i;
  char c;

 again:
  memcpy_P(&c, hs->script, 1);
  switch(c) {
  case ISO_t:
    /* Send a text string. */
    hs->state = HTTP_TEXT;
    hs->dataptr = hs->script + 2;

    /* Calculate length of string. */
    i = 0;
    do {
      memcpy_P(&c, &hs->dataptr[i], 1);
      ++i;
    } while(c != ISO_nl);
    hs->count = i;    
    break;
  case ISO_c:
    /* Call a function. */
    hs->state = HTTP_FUNC;
    hs->dataptr = NULL;
    hs->count = 0;
    /*    uip_reset_acked();*/
    uip_flags &= ~UIP_ACKDATA;
    break;
  case ISO_i:   
    /* Include a file. */
    hs->state = HTTP_FILE;
    memcpy_P(tmp, &hs->script[2], sizeof(tmp));
    if(!httpd_fs_open(tmp, &fsfile)) {
      uip_abort();
      dealloc_state(hs);
    }
    hs->dataptr = fsfile.data;
    hs->count = fsfile.len;
    break;
  case ISO_hash:
    /* Comment line. */
    next_scriptline();
    goto again;
    break;
  case ISO_period:
    /* End of script. */
    hs->state = HTTP_END;
    uip_close();
    dealloc_state(hs);
    break;
  default:
    uip_abort();
    dealloc_state(hs);
    break;
  }
}
/*-----------------------------------------------------------------------------------*/
