Example #1
0
/*
 =======================================================================================================================
 =======================================================================================================================
 */
static PT_THREAD(handle_input (struct httpd_state *s))
{
	PSOCK_BEGIN(&s->sin);

	PSOCK_READTO(&s->sin, ISO_space);

	if(strncmp(s->inputbuf, http_get, 4) != 0)
	{
		PSOCK_CLOSE_EXIT(&s->sin);
	}

	PSOCK_READTO(&s->sin, ISO_space);

	if(s->inputbuf[0] != ISO_slash)
	{
		PSOCK_CLOSE_EXIT(&s->sin);
	}

	if(s->inputbuf[1] == ISO_space)
	{
		strncpy(s->filename, http_index_html, sizeof(s->filename));
	}
	else
	{
		s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;

		/* Process any form input being sent to the server. */
		{
			/*
			 * extern void vApplicationProcessFormInput( char *pcInputString, long
			 * xInputLength ); £
			 * vApplicationProcessFormInput( s->inputbuf, PSOCK_DATALEN(&s->sin) );
			 */
		}

		strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
	}

	/* httpd_log_file(uip_conn->ripaddr, s->filename); */
	s->state = STATE_OUTPUT;

	while(1)
	{
		PSOCK_READTO(&s->sin, ISO_nl);

		if(strncmp(s->inputbuf, http_referer, 8) == 0)
		{
			s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;

			/* httpd_log(&s->inputbuf[9]); */
		}
	}

	PSOCK_END(&s->sin);
}
/*---------------------------------------------------------------------------*/
static PT_THREAD( handle_input ( struct httpd_state *s ) )
{
	PSOCK_BEGIN( &s->sin );
	( void ) PT_YIELD_FLAG;
	PSOCK_READTO( &s->sin, ISO_space );

	if( strncmp(s->inputbuf, http_get, 4) != 0 )
	{
		PSOCK_CLOSE_EXIT( &s->sin );
	}

	PSOCK_READTO( &s->sin, ISO_space );

	if( s->inputbuf[0] != ISO_slash )
	{
		PSOCK_CLOSE_EXIT( &s->sin );
	}

	if( s->inputbuf[1] == ISO_space )
	{
		strncpy( s->filename, http_index_html, sizeof(s->filename) );
	}
	else
	{
		s->inputbuf[PSOCK_DATALEN( &s->sin ) - 1] = 0;
		
		/* Process any form input being sent to the server. */
		#if UIP_CONF_PROCESS_HTTPD_FORMS == 1
		{
			extern void vApplicationProcessFormInput( char *pcInputString );
			vApplicationProcessFormInput( s->inputbuf );
		}
		#endif
		
		strncpy( s->filename, &s->inputbuf[0], sizeof(s->filename) );
	}

	/*  httpd_log_file(uip_conn->ripaddr, s->filename);*/
	s->state = STATE_OUTPUT;

	while( 1 )
	{
		PSOCK_READTO( &s->sin, ISO_nl );

		if( strncmp(s->inputbuf, http_referer, 8) == 0 )
		{
			s->inputbuf[PSOCK_DATALEN( &s->sin ) - 2] = 0;

			/*      httpd_log(&s->inputbuf[9]);*/
		}
	}

	PSOCK_END( &s->sin );
}
Example #3
0
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_input(struct httpd_state *s))
{
  char *LEDptr;

  PSOCK_BEGIN(&s->sin);

  PSOCK_READTO(&s->sin, ISO_space);

  
  if(strncmp(s->inputbuf, http_get, 4) == 0) {

  PSOCK_READTO(&s->sin, ISO_space);

  if(s->inputbuf[0] != ISO_slash) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }

  if(s->inputbuf[1] == ISO_space) {
    strncpy(s->filename, http_index_html, sizeof(s->filename));
  } else {
    s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
    strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
  }

  // Renesas ++
  LEDptr = strstr(s->inputbuf, "LEDA");

  if (LEDptr !=NULL)
  {
      strncpy(LEDbuf, (const char *)(LEDptr), sizeof(LEDbuf));
      LEDflag = 1;
  }
  // End of Renesas ++

  /*  httpd_log_file(uip_conn->ripaddr, s->filename);*/

  s->state = STATE_OUTPUT;

  while(1) {
	PSOCK_READTO(&s->sin, ISO_nl);

    if(strncmp(s->inputbuf, http_referer, 8) == 0) {
	  s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
	  /*      httpd_log(&s->inputbuf[9]);*/
	}
    }
  }else {
  PSOCK_CLOSE_EXIT(&s->sin);
  }
  
  PSOCK_END(&s->sin);
}
Example #4
0
static
PT_THREAD(handle_input(struct httpd_state *s))
{
  PSOCK_BEGIN(&s->sin);

  PSOCK_READTO(&s->sin, ISO_space);

  if(strncmp(s->inputbuf, http_get, 4) == 0) {
    s->request_type = REQUEST_TYPE_GET;
  } else if(strncmp(s->inputbuf, http_put, 4) == 0) {
    s->request_type = REQUEST_TYPE_PUT;
  } else if(strncmp(s->inputbuf, http_post, 5) == 0) {
    s->request_type = REQUEST_TYPE_POST;
  } else if(strncmp(s->inputbuf, http_delete, 7) == 0) {
    s->request_type = REQUEST_TYPE_DELETE;
  } else {
    PSOCK_CLOSE_EXIT(&s->sin);
  }
  PSOCK_READTO(&s->sin, ISO_space);

  if(s->inputbuf[0] != ISO_slash) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }
  s->query = NULL;
#if URLCONV
  s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
  urlconv_tofilename(s->filename, &s->query, s->inputbuf, sizeof(s->filename));
  if(s->filename[1] == 0) {
    strncpy(s->filename, http_index_html, sizeof(s->filename));
  }
#else /* URLCONV */
  if(s->inputbuf[1] == ISO_space) {
    strncpy(s->filename, http_index_html, sizeof(s->filename));
  } else {
    s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
    strncpy(s->filename, s->inputbuf, sizeof(s->filename));
  }
#endif /* URLCONV */
  if(s->query) {
    LOG6LBR_6ADDR(DEBUG, &uip_conn->ripaddr, "Request for '%s?%s' from ", s->filename, s->query);
  } else {
    LOG6LBR_6ADDR(DEBUG, &uip_conn->ripaddr, "Request for '%s' from ", s->filename);
  }

  s->state = STATE_OUTPUT;

  while(1) {
    PSOCK_READTO(&s->sin, ISO_nl);
  }

  PSOCK_END(&s->sin);
}
Example #5
0
static
PT_THREAD(handle_input(struct httpd_state *s))
{

  PSOCK_BEGIN(&s->sin); 

  PSOCK_READTO(&s->sin, ISO_space);

  if(httpd_strncmp(s->inputbuf, httpd_get, 4) != 0) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }
  PSOCK_READTO(&s->sin, ISO_space);

  if(s->inputbuf[0] != ISO_slash) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }

  if(s->inputbuf[1] == ISO_space) {
    httpd_strcpy(s->filename, httpd_indexfn);
  } else {
    s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
    strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
{
    /* Look for ?, if found strip file name and send any following text to the LCD */
    uint8_t i;
    for (i=0;i<sizeof(s->inputbuf);i++) {
      if (s->inputbuf[i]=='?') {
        raven_lcd_show_text(&s->inputbuf[i]);
        if (i<sizeof(s->filename)) s->filename[i]=0;
 //     s->inputbuf[i]=0; //allow multiple beeps with multiple ?'s
      }
      if (s->inputbuf[i]==0) break;
    }
}
  }

  webserver_log_file(&uip_conn->ripaddr, s->filename);

  s->state = STATE_OUTPUT;

  while(1) {
    PSOCK_READTO(&s->sin, ISO_nl);

    if(httpd_strncmp(s->inputbuf, httpd_ref, 8) == 0) {
      s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
      petsciiconv_topetscii(s->inputbuf, PSOCK_DATALEN(&s->sin) - 2);
      webserver_log(s->inputbuf);
    }
  }
  PSOCK_END(&s->sin);
}
Example #6
0
/*---------------------------------------------------------------------------*/
static PT_THREAD (handle_input (struct httpd_state *s))
{
  PSOCK_BEGIN (&s->sin);

  PSOCK_READTO (&s->sin, ISO_space);

  if (strncmp (s->inputbuf, http_get, 4) != 0)
    PSOCK_CLOSE_EXIT (&s->sin);
  
  PSOCK_READTO (&s->sin, ISO_space);

  if (s->inputbuf [0] != ISO_slash)
    PSOCK_CLOSE_EXIT (&s->sin);

  if (s->inputbuf [1] == ISO_space)
    strncpy (s->filename, http_index_html, sizeof (s->filename));
  else 
  {
    char *c;

    s->inputbuf [PSOCK_DATALEN (&s->sin) - 1] = 0;

    if ((c = strstr (s->inputbuf, "?")))
      *c++ = '\0';

    strncpy (s->filename, &s->inputbuf [0], sizeof (s->filename));

    if (!strcmp (s->filename, "/led.shtml"))
    {
      if (c && strstr (c, "LED2=1"))
        GPIO0_FIOCLR = GPIO_IO_P11;
      else
        GPIO0_FIOSET = GPIO_IO_P11;
    }
  }

  s->state = STATE_OUTPUT;

  while (1) 
  {
    PSOCK_READTO (&s->sin, ISO_nl);

    if (strncmp (s->inputbuf, http_referer, 8) == 0)
      s->inputbuf [PSOCK_DATALEN (&s->sin) - 2] = 0;
  }

  PSOCK_END (&s->sin);
}
Example #7
0
static
PT_THREAD(handle_connection(struct psock *p))
{
  static int seq_id = 1;
  
  PSOCK_BEGIN(p);
  
  while(1){
  
    PSOCK_READTO(p, '\r');
    
    buf[PSOCK_DATALEN(p)-1] = '\0';
    PRINTF("Server received: %s", buf);
    PRINTF("\r\nFrom ");
    PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
    PRINTF("\r\n");    
    
    PRINTF("Responding with message: ");
    sprintf((char*)buf, "Hello from the server! (%d)\r", seq_id++);
    PRINTF("%s\r\n", buf);
    PSOCK_SEND_STR(p, (char*)buf);
  
  }  
  
  PSOCK_END(p);
    
}
Example #8
0
void
UIPClient::dataReceived(uip_tcp_appstate_t *s)
{
  if (uip_userdata_t *u = (uip_userdata_t *) s->user)
    {
      u->in_len += PSOCK_DATALEN(&s->p);
    }
}
Example #9
0
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_input(struct httpd_state *s))
{
  PSOCK_BEGIN(&s->sin);

  PSOCK_READTO(&s->sin, ISO_space);
  
  if(strncmp(s->inputbuf, http_get, 4) != 0) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }
  PSOCK_READTO(&s->sin, ISO_space);

  if(s->inputbuf[0] != ISO_slash) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }

#if URLCONV
  s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
  urlconv_tofilename(s->filename, s->inputbuf, sizeof(s->filename));
#else /* URLCONV */
  if(s->inputbuf[1] == ISO_space) {
    strncpy(s->filename, http_index_htm, sizeof(s->filename));
  } else {
    s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
    strncpy(s->filename, s->inputbuf, sizeof(s->filename));
  }
#endif /* URLCONV */

  petsciiconv_topetscii(s->filename, sizeof(s->filename));
  webserver_log_file(&uip_conn->ripaddr, s->filename);
  petsciiconv_toascii(s->filename, sizeof(s->filename));
  s->state = STATE_OUTPUT;

  while(1) {
    PSOCK_READTO(&s->sin, ISO_nl);

    if(strncmp(s->inputbuf, http_referer, 8) == 0) {
      s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
      petsciiconv_topetscii(s->inputbuf, PSOCK_DATALEN(&s->sin) - 2);
      webserver_log(s->inputbuf);
    }
  }
  
  PSOCK_END(&s->sin);
}
Example #10
0
static int handle_connection(struct socket_app_state *s)
{
  PSOCK_BEGIN(&s->p);
  PSOCK_READTO(&s->p, '\n');
  memcpy(buffer,s->inputbuffer,PSOCK_DATALEN(&s->p));
  memset(s->inputbuffer, 0x00, sizeof(s->inputbuffer));
  PSOCK_SEND_STR(&s->p, outBuffer);
  PSOCK_END(&s->p);
}
Example #11
0
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_input(struct httpd_state *s))
{
  PSOCK_BEGIN(&s->sin);

  PSOCK_READTO(&s->sin, ISO_space);

  // GET Request
  if(!strncmp(s->inputbuf, http_get, 4)) {
  //PSOCK_CLOSE_EXIT(&s->sin);
		s->method = GET;
  } else {
		s->method = POST;
  }
  PSOCK_READTO(&s->sin, ISO_space);

  if(s->inputbuf[0] != ISO_slash) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }

#if URLCONV
  s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
  urlconv_tofilename(s->filename, s->inputbuf, sizeof(s->filename));
#else /* URLCONV */
    s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
    strncpy(s->filename, s->inputbuf, sizeof(s->filename));
#endif /* URLCONV */

  //webserver_log_file(&uip_conn->ripaddr, s->filename);

  s->state = STATE_OUTPUT;

  while(1) {
    PSOCK_READTO(&s->sin, ISO_nl);
#if 0
    if(strncmp(s->inputbuf, http_referer, 8) == 0) {
      s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
      webserver_log(s->inputbuf);
    }
#endif
  }

  PSOCK_END(&s->sin);
}
Example #12
0
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_input(struct httpd_state *s))
{
  PSOCK_BEGIN(&s->sin);

  PSOCK_READTO(&s->sin, ISO_space);
	//printf("http 1: %s\r\n", s->inputbuf);
  if(strncmp(s->inputbuf, http_get, 4) != 0) {
	
    PSOCK_CLOSE_EXIT(&s->sin);
  }
  PSOCK_READTO(&s->sin, ISO_space);
  //printf("http 2: %s\r\n", s->inputbuf);

  if(s->inputbuf[0] != ISO_slash) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }

  if(s->inputbuf[1] == ISO_space) {
    strncpy(s->filename, http_index_html, sizeof(s->filename));
  } else {
    s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
    strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
  }

  //*  
   //httpd_log_file(uip_conn->ripaddr, s->filename);
  //*/
  
  s->state = STATE_OUTPUT;

  while(1) {
    PSOCK_READTO(&s->sin, ISO_nl);

    if(strncmp(s->inputbuf, http_referer, 8) == 0) {
      s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
      /*      httpd_log(&s->inputbuf[9]);*/
    }
  }
  
  PSOCK_END(&s->sin);
  //nEth = 0;
}
Example #13
0
/*
 * A protosocket always requires a protothread. The protothread
 * contains the code that uses the protosocket. We define the
 * protothread here.
 */
static
PT_THREAD(handle_connection(struct psock *p))
{
  /*
   * A protosocket's protothread must start with a PSOCK_BEGIN(), with
   * the protosocket as argument.
   *
   * Remember that the same rules as for protothreads apply: do NOT
   * use local variables unless you are very sure what you are doing!
   * Local (stack) variables are not preserved when the protothread
   * blocks.
   */
  PSOCK_BEGIN(p);

  /*
   * We start by sending out a welcoming message. The message is sent
   * using the PSOCK_SEND_STR() function that sends a null-terminated
   * string.
   */
  PSOCK_SEND_STR(p, "Welcome, please type something and press return.\n");
  
  /*
   * Next, we use the PSOCK_READTO() function to read incoming data
   * from the TCP connection until we get a newline character. The
   * number of bytes that we actually keep is dependant of the length
   * of the input buffer that we use. Since we only have a 10 byte
   * buffer here (the buffer[] array), we can only remember the first
   * 10 bytes received. The rest of the line up to the newline simply
   * is discarded.
   */
  PSOCK_READTO(p, '\n');
  
  /*
   * And we send back the contents of the buffer. The PSOCK_DATALEN()
   * function provides us with the length of the data that we've
   * received. Note that this length will not be longer than the input
   * buffer we're using.
   */
  PSOCK_SEND_STR(p, "Got the following data: ");
  PSOCK_SEND(p, buffer, PSOCK_DATALEN(p));
  PSOCK_SEND_STR(p, "Good bye!\r\n");

  /*
   * We close the protosocket.
   */
  PSOCK_CLOSE(p);

  /*
   * And end the protosocket's protothread.
   */
  PSOCK_END(p);
}
Example #14
0
static
PT_THREAD(handle_input(struct httpd_state *s))
{

  PSOCK_BEGIN(&s->sin); 

  PSOCK_READTO(&s->sin, ISO_space);

  if(httpd_strncmp(s->inputbuf, httpd_get, 4) != 0) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }
  PSOCK_READTO(&s->sin, ISO_space);

  if(s->inputbuf[0] != ISO_slash) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }

  if(s->inputbuf[1] == ISO_space) {
    httpd_strcpy(s->filename, httpd_indexfn);
  } else {
    s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
    strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
  }

  webserver_log_file(&uip_conn->ripaddr, s->filename);

  s->state = STATE_OUTPUT;

  while(1) {
    PSOCK_READTO(&s->sin, ISO_nl);

    if(httpd_strncmp(s->inputbuf, httpd_ref, 8) == 0) {
      s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
      petsciiconv_topetscii(s->inputbuf, PSOCK_DATALEN(&s->sin) - 2);
      webserver_log(s->inputbuf);
    }
  }
  PSOCK_END(&s->sin);
}
Example #15
0
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_input(struct httpd_state *s))
{
  PSOCK_BEGIN(&s->sin);

  PSOCK_READTO(&s->sin, ' ');
  
  if(strncmp(s->inputbuf, "GET ", 4) != 0) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }
  PSOCK_READTO(&s->sin, ' ');

  if(s->inputbuf[0] != '/') {
    PSOCK_CLOSE_EXIT(&s->sin);
  }

  if(s->inputbuf[1] == ' ') {
    strncpy(s->filename, "index.html", sizeof(s->filename));
  } else {
    s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
    strncpy(s->filename, &s->inputbuf[1], sizeof(s->filename));
  }

  //  webserver_log_file(&uip_conn->ripaddr, s->filename);
  libputs_arch(s->filename);
  s->state = STATE_OUTPUT;

  while(1) {
    PSOCK_READTO(&s->sin, '\n');

    if(strncmp(s->inputbuf, "Referer:", 8) == 0) {
      s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
      libputs_arch(&s->inputbuf[9]);
      //      webserver_log(&s->inputbuf[9]);
    }
  }
  
  PSOCK_END(&s->sin);
}
Example #16
0
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_input(struct httpd_state *s))
{
  PSOCK_BEGIN(&s->sin);

  PSOCK_READTO(&s->sin, ISO_space);
  
  if(strncmp(s->inputbuf, http_get, 4) != 0) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }
  PSOCK_READTO(&s->sin, ISO_space);

  if(s->inputbuf[0] != ISO_slash) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }

  if(s->inputbuf[1] == ISO_space) {
    strncpy(s->filename, http_index_html, sizeof(s->filename));
  } else {
    s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
    strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
  }

  libputs_arch(s->filename);
  
  s->state = STATE_OUTPUT;

  while(1) {
    PSOCK_READTO(&s->sin, ISO_nl);

    if(strncmp(s->inputbuf, http_referer, 8) == 0) {
      s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
    }
  }
  
  PSOCK_END(&s->sin);
}
Example #17
0
/* -------------------------------------------------------------------------- */
static PT_THREAD(handle_connection(struct psock *p))
{
    // So, as always let's start
    PSOCK_BEGIN(p);

    // Let's send a hello world
    PSOCK_SEND_STR(p, "Welcome, please type something and press return.\n");

    // Let's block this thread untile a new line is received
    PSOCK_READTO(p, '\n');

    // And what we receive, we send it back, MUAHAHA
    PSOCK_SEND_STR(p, "Got the following data: ");
    PSOCK_SEND(p, buffer, PSOCK_DATALEN(p));
    PSOCK_SEND_STR(p, "Good bye!\r\n");

    // Finally close the socket
    PSOCK_CLOSE(p);

    // The End...
    PSOCK_END(p);
}
Example #18
0
/*---------------------------------------------------------------------------*/
static
PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr))
{
  char *ptr;
  PSOCK_BEGIN(&s->sout);

  PSOCK_GENERATOR_SEND(&s->sout, generate_status, (char *) statushdr);

  ptr = strrchr(s->filename, ISO_period);
  if (httpd_strncmp("4", statushdr, 1) == 0) { //404
    PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_htm);
  } else if (ptr == NULL) {
#if WEBSERVER_CONF_BIN
    PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_bin);
#else
    PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_htm);
#endif 
  } else {
    ptr++;
#if WEBSERVER_CONF_INCLUDE || WEBSERVER_CONF_CGI
    if (httpd_strncmp(ptr, &httpd_mime_htm[5], 3) == 0 || httpd_strncmp(ptr, &httpd_str_shtml[1], 4) == 0) {
#else
    if (httpd_strncmp(ptr, &httpd_mime_htm[5], 3) == 0) {
#endif
      PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_htm);
#if WEBSEVER_CONF_CSS
    } else if (httpd_strcmp(ptr, &httpd_mime_css[5]) == 0) {
      PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_css);
#endif
#if WEBSERVER_CONF_PNG
    } else if (httpd_strcmp(ptr, &httpd_mime_png[6]) == 0) {
      PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_png);
#endif
#if WEBSERVER_CONF_GIF
    } else if (httpd_strcmp(ptr, &httpd_mime_gif[6]) == 0) {
      PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_gif);
#endif
#if WEBSERVER_CONF_JPG
    } else if (httpd_strcmp(ptr, httpd_mime_jpg) == 0) {
      PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_jpg);
#endif
#if WEBSERVER_CONF_TXT
    } else {
      PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_txt);
#endif
    }
  }
  PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_output(struct httpd_state *s))
{
  char *ptr;

  PT_BEGIN(&s->outputpt);

#if DEBUGLOGIC
  httpd_strcpy(s->filename, httpd_str_indexfn);
#endif

  s->fd = httpd_fs_open(s->filename, HTTPD_FS_READ);
  if (s->fd == -1) { // Opening file failed.

    /* TODO: try index.htm ? */
#if WEBSERVER_CONF_INCLUDE || WEBSERVER_CONF_CGI
    /* If index.html not found try index.htm */
    if (httpd_strcmp(s->filename, httpd_str_indexfn) == 0) {
      httpd_strcpy(s->filename, httpd_str_indexfn3);
    }
    s->fd = httpd_fs_open(s->filename, HTTPD_FS_READ);
    if (s->fd != -1) {
      goto sendfile;
    }
    /* If index.html not found try index.shtml */
    if (httpd_strcmp(s->filename, httpd_str_indexfn) == 0) {
      httpd_strcpy(s->filename, httpd_str_indexsfn);
    }
    s->fd = httpd_fs_open(s->filename, HTTPD_FS_READ);
    if (s->fd == -1) {
      PRINTD("Opening %s failed\n", s->filename);
      goto psock_close;
    } else {
      goto sendfile;
    }
#endif
    /* If nothing was found, send 404 page */
    httpd_strcpy(s->filename, httpd_str_404fn);
    s->fd = httpd_fs_open(s->filename, HTTPD_FS_READ);
    PT_WAIT_THREAD(&s->outputpt, send_headers(s, httpd_str_404notf));
    PT_WAIT_THREAD(&s->outputpt, send_file(s));

  } else { // Opening file succeeded.

sendfile:
    PT_WAIT_THREAD(&s->outputpt, send_headers(s, httpd_str_200ok));
#if WEBSERVER_CONF_INCLUDE || WEBSERVER_CONF_CGI
    /* If filename ends with .shtml, scan file for script includes or cgi */
    ptr = strchr(s->filename, ISO_period);
    if ((ptr != NULL && httpd_strncmp(ptr, httpd_str_shtml, 6) == 0)
            || httpd_strcmp(s->filename, httpd_str_indexfn) == 0) {
      PT_INIT(&s->scriptpt);
      PT_WAIT_THREAD(&s->outputpt, handle_scripts(s));
    } else {
#else
    if (1) {
#endif
      PT_WAIT_THREAD(&s->outputpt, send_file(s));
      httpd_fs_close(s->fd);
    }
  }
psock_close:
  PSOCK_CLOSE(<y & s->sout);
  PT_END(&s->outputpt);
}
/*---------------------------------------------------------------------------*/
#if WEBSERVER_CONF_PASSQUERY
char httpd_query[WEBSERVER_CONF_PASSQUERY];
#endif

static
PT_THREAD(handle_input(struct httpd_state *s))
{

  PSOCK_BEGIN(&s->sin);

  PSOCK_READTO(&s->sin, ISO_space);

  if (httpd_strncmp(s->inputbuf, httpd_str_get, 4) != 0) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }
  PSOCK_READTO(&s->sin, ISO_space);

  if (s->inputbuf[0] != ISO_slash) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }

  if (s->inputbuf[1] == ISO_space) {
    httpd_strcpy(s->filename, httpd_str_indexfn);
  } else {
    uint8_t i;
    for (i = 0; i<sizeof (s->filename) + 1; i++) {
      if (i >= (PSOCK_DATALEN(&s->sin) - 1)) break;
      if (s->inputbuf[i] == ISO_space) break;
#if WEBSERVER_CONF_PASSQUERY
      /* Query string is left in the httpd_query buffer until zeroed by the application! */
      if (s->inputbuf[i] == ISO_qmark) {
        strncpy(httpd_query, &s->inputbuf[i + 1], sizeof (httpd_query));
        break;
      }
#endif
      s->filename[i] = s->inputbuf[i];
    }
    s->filename[i] = 0;
  }

#if WEBSERVER_CONF_LOG
  webserver_log_file(&uip_conn->ripaddr, s->filename);
  //  webserver_log(httpd_query);
#endif
#if WEBSERVER_CONF_LOADTIME
  s->pagetime = clock_time();
#endif
  s->state = STATE_OUTPUT;
  while (1) {
    PSOCK_READTO(&s->sin, ISO_nl);
#if WEBSERVER_CONF_LOG && WEBSERVER_CONF_REFERER
    if (httpd_strncmp(s->inputbuf, httpd_str_ref, 8) == 0) {
      s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
      petsciiconv_topetscii(s->inputbuf, PSOCK_DATALEN(&s->sin) - 2);
      webserver_log(s->inputbuf);
    }
#endif
  }
  PSOCK_END(&s->sin);
}
Example #19
0
//处理HTTP输入数据
static PT_THREAD(handle_input(struct httpd_state *s))
{		    	  
	char *strx;
	u8 dbuf[17];
	PSOCK_BEGIN(&s->sin);		 
	PSOCK_READTO(&s->sin, ISO_space);	 
	if(strncmp(s->inputbuf, http_get, 4)!=0)PSOCK_CLOSE_EXIT(&s->sin);	//比较客户端浏览器输入的指令是否是申请WEB指令 “GET ” 	   
	PSOCK_READTO(&s->sin, ISO_space);		     						//" "
	if(s->inputbuf[0] != ISO_slash)PSOCK_CLOSE_EXIT(&s->sin);		 	//判断第一个(去掉IP地址之后)数据,是否是"/"
	if(s->inputbuf[1] == ISO_space||s->inputbuf[1] == '?') 				//第二个数据是空格/问号
	{ 
		if(s->inputbuf[1]=='?'&&s->inputbuf[6]==0x31)//LED1  
		{
			printf("Change LED0 Status\r\n");
			LED0 = !LED0;	
			strx=strstr((const char*)(data_index_html+13),"LED0状态");  
			if(strx)//存在"LED0状态"这个字符串
			{
				strx=strstr((const char*)strx,"color:#");//找到"color:#"字符串
				if(LED0)//LED0灭
				{
					strncpy(strx+7,"5B5B5B",6);	//灰色
					strncpy(strx+24,"灭",2);	//灭
					strx=strstr((const char*)strx,"http:");//找到"http:"字符串 
					strncpy(strx,(const char*)LED_OFF_PIC_ADDR,strlen((const char*)LED_OFF_PIC_ADDR));//LED0灭图片	  
				}else
				{
					strncpy(strx+7,"FF0000",6);	//红色
					strncpy(strx+24,"亮",2);	//"亮"
					strx=strstr((const char*)strx,"http:");//找到"http:"字符串 
					strncpy(strx,(const char*)LED0_ON_PIC_ADDR,strlen((const char*)LED0_ON_PIC_ADDR));//LED0亮图片	  
				}	
			}  
		}
		else if(s->inputbuf[1]=='?'&&s->inputbuf[6]==0x32)//LED2  
		{
			printf("Change LED1 Status\r\n");
			LED1 = !LED1;	
			strx=strstr((const char*)(data_index_html+13),"LED1状态");  
			if(strx)//存在"LED1状态"这个字符串
			{
				strx=strstr((const char*)strx,"color:#");//找到"color:#"字符串
				if(LED1)//LED1灭
				{
					strncpy(strx+7,"5B5B5B",6);	//灰色
					strncpy(strx+24,"灭",2);	//灭
					strx=strstr((const char*)strx,"http:");//找到"http:"字符串 
					strncpy(strx,(const char*)LED_OFF_PIC_ADDR,strlen((const char*)LED_OFF_PIC_ADDR));//LED1灭图片	  
				}else
				{
					strncpy(strx+7,"00FF00",6);	//绿色
					strncpy(strx+24,"亮",2);	//"亮"
					strx=strstr((const char*)strx,"http:");//找到"http:"字符串 
					strncpy(strx,(const char*)LED1_ON_PIC_ADDR,strlen((const char*)LED1_ON_PIC_ADDR));//LED1亮图片	  
				}	
			} 
		}
		
		strx = strstr((const char*)(data_index_html+13),"℃");//找到"℃"字符
		if(strx)
		{
//			get_temperature(dbuf);	//得到温度	  
			strncpy(strx-4,(const char*)dbuf,4);	//更新温度
			printf("Update Temperature\r\n");			
		}
		strx=strstr((const char*)strx,"RTC时间:");//找到"RTC时间:"字符
		if(strx)
		{
//			get_time(dbuf);			//得到时间  
			strncpy(strx+33,(const char*)dbuf,16);	//更新时间
			printf("Update RTC\r\n");
		}
		strncpy(s->filename, http_index_html, sizeof(s->filename));
	}
	else //如果不是' '/'?'
	{
		s->inputbuf[PSOCK_DATALEN(&s->sin)-1] = 0;
		strncpy(s->filename,&s->inputbuf[0],sizeof(s->filename));
	}   
	s->state = STATE_OUTPUT;	    
	while(1) 
	{
		PSOCK_READTO(&s->sin, ISO_nl);
		if(strncmp(s->inputbuf, http_referer, 8) == 0) 
		{
			s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;		   
		}
	}								    
	PSOCK_END(&s->sin);
}
Example #20
0
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_input(struct httpd_state *s))
{
  PSOCK_BEGIN(&s->sin);
#if defined(HTTP_POST_SUPPORT)
  int cont_len = 0;
#endif

  PSOCK_READTO(&s->sin, ISO_space);

  if(strncmp_P(s->inputbuf, http_get, 3) == 0) {
    s->request_type = GET;
#if defined(HTTP_POST_SUPPORT)
  } else if(strncmp_P(s->inputbuf, http_post, 4) == 0) {
    s->request_type = POST;
#endif
  } else {
    PSOCK_CLOSE_EXIT(&s->sin);
  }
  PSOCK_READTO(&s->sin, ISO_space);

  if(s->inputbuf[0] != ISO_slash) {
    PSOCK_CLOSE_EXIT(&s->sin);
  }

    /* read and store the file name */
    if(s->inputbuf[1] == ISO_space) {
        strncpy_P(s->filename, http_index_html, sizeof(s->filename));
    } else {
        s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;

#if defined(HTTP_GET_PARAM_SUPPORT)
    // note this code block taken from uhttpd-avr project
        int i;
        for(i=0 ; s->inputbuf[i]!=0 && s->inputbuf[i] != ISO_question ; i++);

        if( s->inputbuf[i] == ISO_question )
        {
            s->inputbuf[i]=0;
            strncpy(s->param,&s->inputbuf[i+1],sizeof(s->param));
            s->param_len = strlen(s->param);
        }
        else
        {
            s->param[0] = 0;
            s->param_len = 0;
        }
    // end note
#endif                                                      
        strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
    }

  /*  httpd_log_file(uip_conn->ripaddr, s->filename);*/

  s->state = STATE_OUTPUT;

  /* read all of the clients input data */
  while(1) {
    PSOCK_READTO(&s->sin, ISO_nl);

#if defined(HTTP_POST_SUPPORT)
    if(s->request_type == POST) {
      if(cont_len != 0) {
          /* does this line contain any data */
          if(PSOCK_DATALEN(&s->sin) > 2) {
			s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
            strncpy(s->param,&s->inputbuf[0],sizeof(s->param));
            s->param_len = strlen(s->param);
			break;
          }
      }else if(strncmp_P(s->inputbuf, http_content_length, 15) == 0) {
        s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
        cont_len = atoi(&s->inputbuf[16]);
        if (cont_len > MAX_PARAM_DATA) {
            strncpy_P(s->filename, http_413_html, sizeof(s->filename));
			break;
        }
        s->param[0] = 0;
        s->param_len = 0;
      }
    }
#endif
#if 0 /* compile out but, leave as example */
    if(strncmp_P(s->inputbuf, http_referer, 8) == 0) {
      s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
      /*      httpd_log(&s->inputbuf[9]);*/
    }
#endif
  }
  
  PSOCK_END(&s->sin);
}
Example #21
0
static
PT_THREAD(handle_input(struct httpd_state *s))
{
	int found = 0;

	PSOCK_BEGIN(&s->sin);

	PSOCK_READTO(&s->sin, ISO_space);

	if(httpd_strncmp(s->inputbuf, httpd_get, 4) == 0) {

		PSOCK_READTO(&s->sin, ISO_space);

		if(s->inputbuf[0] != ISO_slash) {
			PSOCK_CLOSE_EXIT(&s->sin);
		}

		if(s->inputbuf[1] == ISO_space) {
			httpd_strcpy(s->filename, httpd_indexfn);
		} else {
			s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
			strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));

			/* Look for ?, if found strip file name and send any following text to the LCD */
			uint8_t i;
			for (i=0;i<sizeof(s->inputbuf);i++) {
				if (s->inputbuf[i]=='?') {
					if (i<sizeof(s->filename)) s->filename[i]=0;
					//     s->inputbuf[i]=0; //allow multiple beeps with multiple ?'s
				}
				if (s->inputbuf[i]==0) break;
			}

		}
	}
	else if(httpd_strncmp(s->inputbuf, httpd_post, 5) == 0) {

		PSOCK_READTO(&s->sin, ISO_space);

		if(s->inputbuf[0] != ISO_slash) {
			PSOCK_CLOSE_EXIT(&s->sin);
		}
		if (httpd_strncmp(&s->inputbuf[1], httpd_config_file, sizeof(httpd_config_file)-1) == 0)  {

			s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
			strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
			/* Look for ?, if found strip file name*/
			uint8_t i;
			for (i=0;i<sizeof(s->inputbuf);i++) {
				if (s->inputbuf[i]=='?') {
					if (i<sizeof(s->filename)) s->filename[i]=0;
				}
				if (s->inputbuf[i]==0) break;
			}
			//parse config data
			found = 0;

			//look for the combination "\r\n\r\n"; the post data follow thereafter
			while (!found)
			{
				PSOCK_READTO(&s->sin, ISO_nl);
				PSOCK_READTO(&s->sin, ISO_cr);
				if (PSOCK_DATALEN(&s->sin) == 1)
				{
					PSOCK_READTO(&s->sin, ISO_nl);
					found=1;
				}
			}

			PSOCK_READTO(&s->sin, ISO_equal);
			//check for domain_name
			PSOCK_READTO(&s->sin, ISO_amper);
			if(s->inputbuf[0] != ISO_amper) {
				char tmp[nvm_size(domain_name)];
				memset(tmp, 0, sizeof (tmp));
				memcpy(tmp, s->inputbuf, PSOCK_DATALEN(&s->sin) - 1);
				nvm_write_block(domain_name, tmp, sizeof(tmp));
			}

			PSOCK_READTO(&s->sin, ISO_equal);
			//check for relay_default_state
			PSOCK_READTO(&s->sin, ISO_amper);
			if(s->inputbuf[0] == '1')
				set_relay_default(0);
			else if (s->inputbuf[0] == '0')
				set_relay_default(1);

#if S0_ENABLE
			PSOCK_READTO(&s->sin, ISO_equal);
			//check for s0 calibration value
			PSOCK_READTO(&s->sin, ISO_amper);
			if(s->inputbuf[0] != ISO_amper) {
                metering_set_s0_calibration((uint16_t)atoi(s->inputbuf));
            }
#endif
		}
		else if (httpd_strncmp(&s->inputbuf[1], httpd_socket_status_file, sizeof(httpd_socket_status_file)-1) == 0) {
			// toggle button has been pressed

			s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
			strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
			/* Look for ?, if found strip file name*/
			uint8_t i;
			for (i=0;i<sizeof(s->inputbuf);i++) {
				if (s->inputbuf[i]=='?') {
					if (i<sizeof(s->filename)) s->filename[i]=0;
				}
				if (s->inputbuf[i]==0) break;
			}

			relay_toggle();

	} else {
			PSOCK_CLOSE_EXIT(&s->sin);
		}
	}	else {
		PSOCK_CLOSE_EXIT(&s->sin);
	}
	webserver_log_file(&uip_conn->ripaddr, s->filename);

	s->state = (s->state == STATE_ERROR) ? STATE_OUTPUT_ERROR : STATE_OUTPUT;

	while(1) {
		PSOCK_READTO(&s->sin, ISO_nl);
		if(httpd_strncmp(s->inputbuf, httpd_ref, 8) == 0) {
			s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
			petsciiconv_topetscii(s->inputbuf, PSOCK_DATALEN(&s->sin) - 2);
			webserver_log(s->inputbuf);
		}
	}
	PSOCK_END(&s->sin);
}
Example #22
0
static
PT_THREAD(handle_request(connection_state_t* conn_state))
{
    static int error;
    const char* content_len;

    PSOCK_BEGIN(&(conn_state->sin));

    content_len = NULL;

    error = HTTP_NO_ERROR; /*always reinit static variables due to protothreads*/

    PRINTF("Request--->\n");

    //read method
    PSOCK_READTO(&(conn_state->sin), ' ');

    if (!is_method_handled(conn_state, conn_state->inputbuf)) {
        /*method not handled*/
        http_set_status(&conn_state->response, SERVICE_UNAVAILABLE_503);
        conn_state->state = STATE_OUTPUT;
    } else {
        /*read until the end of url*/
        PSOCK_READTO(&(conn_state->sin), ' ');

        /*-1 is needed since it also includes space char*/
        if (conn_state->inputbuf[PSOCK_DATALEN(&(conn_state->sin)) - 1] != ' ' ) {
            error = HTTP_URL_TOO_LONG;
        }

        conn_state->inputbuf[PSOCK_DATALEN(&(conn_state->sin)) - 1] = 0;

        PRINTF("Read URL:%s\n", conn_state->inputbuf);

        if (error == HTTP_NO_ERROR) {
            error = parse_url(conn_state, conn_state->inputbuf);
        }

        if (error != HTTP_NO_ERROR) {
            if (error == HTTP_URL_TOO_LONG) {
                http_set_status(&conn_state->response, REQUEST_URI_TOO_LONG_414);
            } else {
                http_set_status(&conn_state->response, BAD_REQUEST_400);
            }

            conn_state->state = STATE_OUTPUT;
        } else {
            /*read until the end of HTTP version - not used yet*/
            PSOCK_READTO(&(conn_state->sin), LINE_FEED_CHAR);

            PRINTF("After URL:%s\n", conn_state->inputbuf);

            /*FIXME : PSOCK_READTO takes just a single delimiter so I read till the end of line
            but now it may not fit in the buffer. If PSOCK_READTO would take two delimiters,
            we would have read until : and <CR> so it would not be blocked.*/

            /*Read the headers and store the necessary ones*/
            do {
                /*read the next line*/
                PSOCK_READTO(&(conn_state->sin), LINE_FEED_CHAR);
                conn_state->inputbuf[ PSOCK_DATALEN(&(conn_state->sin)) - 1] = 0;

                /*if headers finished then stop the infinite loop*/
                if (conn_state->inputbuf[0] == CARRIAGE_RETURN_CHAR || conn_state->inputbuf[0] == 0) {
                    PRINTF("Finished Headers!\n\n");
                    break;
                }

                parse_header(conn_state, conn_state->inputbuf);
            }
            while(1);

            content_len = get_header(conn_state->request.headers, HTTP_HEADER_NAME_CONTENT_LENGTH);
            if (content_len) {
                conn_state->request.payload_len = atoi(content_len);

                PRINTF("Post Data Size string: %s int: %d\n", content_len, conn_state->request.payload_len);
            }

            if (conn_state->request.payload_len) {
                static uint16_t read_bytes = 0;
                /*init the static variable again*/
                read_bytes = 0;

                conn_state->request.payload = allocate_buffer(conn_state->request.payload_len + 1);

                if (conn_state->request.payload) {
                    do {
                        PSOCK_READBUF(&(conn_state->sin));
                        /*null terminate the buffer in case it is a string.*/
                        conn_state->inputbuf[PSOCK_DATALEN(&(conn_state->sin))] = 0;

                        memcpy(conn_state->request.payload + read_bytes, conn_state->inputbuf, PSOCK_DATALEN(&(conn_state->sin)));

                        read_bytes += PSOCK_DATALEN(&(conn_state->sin));

                    } while (read_bytes < conn_state->request.payload_len);

                    conn_state->request.payload[read_bytes++] = 0;

                    PRINTF("PostData => %s \n", conn_state->request.payload);
                } else {
                    error = HTTP_MEMORY_ALLOC_ERR;
                }
            }

            if (error == HTTP_NO_ERROR) {
                if (service_cbk) {
                    service_cbk(&conn_state->request, &conn_state->response);
                }
            } else {
                PRINTF("Error:%d\n",error);
                http_set_status(&conn_state->response, INTERNAL_SERVER_ERROR_500);
            }

            conn_state->state = STATE_OUTPUT;
        }
    }

    PSOCK_END(&(conn_state->sin));
}
Example #23
0
static PT_THREAD(handle_mqtt_connection(mqtt_state_t* state))
{
  static struct etimer keepalive_timer;

  uint8_t msg_type;
  uint8_t msg_qos;
  uint16_t msg_id;

  PSOCK_BEGIN(&state->ps);

  // Initialise and send CONNECT message
  mqtt_msg_init(&state->mqtt_connection, state->out_buffer, state->out_buffer_length);
  state->outbound_message =  mqtt_msg_connect(&state->mqtt_connection, state->connect_info);
  PSOCK_SEND(&state->ps, state->outbound_message->data, state->outbound_message->length);
  state->outbound_message = NULL;

  // Wait for CONACK message
  PSOCK_READBUF_LEN(&state->ps, 2);
  if(mqtt_get_type(state->in_buffer) != MQTT_MSG_TYPE_CONNACK)
    PSOCK_CLOSE_EXIT(&state->ps);
  
  // Tell the client we're connected
  mqtt_flags |= MQTT_FLAG_CONNECTED;
  complete_pending(state, MQTT_EVENT_TYPE_CONNECTED);

  // Setup the keep alive timer and enter main message processing loop
  etimer_set(&keepalive_timer, CLOCK_SECOND * state->connect_info->keepalive);
  while(1)
  {
    // Wait for something to happen: 
    //   new incoming data, 
    //   new outgoing data, 
    //   keep alive timer expired
    PSOCK_WAIT_UNTIL(&state->ps, PSOCK_NEWDATA(&state->ps) || 
                                 state->outbound_message != NULL ||
                                 etimer_expired(&keepalive_timer));

    // If there's a new message waiting to go out, then send it
    if(state->outbound_message != NULL)
    {
      PSOCK_SEND(&state->ps, state->outbound_message->data, state->outbound_message->length);
      state->outbound_message = NULL;

      // If it was a PUBLISH message with QoS-0 then tell the client it's done
      if(state->pending_msg_type == MQTT_MSG_TYPE_PUBLISH && state->pending_msg_id == 0)
        complete_pending(state, MQTT_EVENT_TYPE_PUBLISHED);

      // Reset the keepalive timer as we've just sent some data
      etimer_restart(&keepalive_timer);
      continue;
    }

    // If the keep-alive timer expired then prepare a ping for sending
    // and reset the timer
    if(etimer_expired(&keepalive_timer))
    {
      state->outbound_message = mqtt_msg_pingreq(&state->mqtt_connection);
      etimer_reset(&keepalive_timer);
      continue;
    }

    // If we get here we must have woken for new incoming data, 
    // read and process it.
    PSOCK_READBUF_LEN(&state->ps, 2);
    
    state->message_length_read = PSOCK_DATALEN(&state->ps);
    state->message_length = mqtt_get_total_length(state->in_buffer, state->message_length_read);

    msg_type = mqtt_get_type(state->in_buffer);
    msg_qos  = mqtt_get_qos(state->in_buffer);
    msg_id   = mqtt_get_id(state->in_buffer, state->in_buffer_length);
    switch(msg_type)
    {
      case MQTT_MSG_TYPE_SUBACK:
        if(state->pending_msg_type == MQTT_MSG_TYPE_SUBSCRIBE && state->pending_msg_id == msg_id)
          complete_pending(state, MQTT_EVENT_TYPE_SUBSCRIBED);
        break;
      case MQTT_MSG_TYPE_UNSUBACK:
        if(state->pending_msg_type == MQTT_MSG_TYPE_UNSUBSCRIBE && state->pending_msg_id == msg_id)
          complete_pending(state, MQTT_EVENT_TYPE_UNSUBSCRIBED);
        break;
      case MQTT_MSG_TYPE_PUBLISH:
        if(msg_qos == 1)
          state->outbound_message = mqtt_msg_puback(&state->mqtt_connection, msg_id);
        else if(msg_qos == 2)
          state->outbound_message = mqtt_msg_pubrec(&state->mqtt_connection, msg_id);

        deliver_publish(state, state->in_buffer, state->message_length_read);
        break;
      case MQTT_MSG_TYPE_PUBACK:
        if(state->pending_msg_type == MQTT_MSG_TYPE_PUBLISH && state->pending_msg_id == msg_id)
          complete_pending(state, MQTT_EVENT_TYPE_PUBLISHED);
        break;
      case MQTT_MSG_TYPE_PUBREC:
        state->outbound_message = mqtt_msg_pubrel(&state->mqtt_connection, msg_id);
        break;
      case MQTT_MSG_TYPE_PUBREL:
        state->outbound_message = mqtt_msg_pubcomp(&state->mqtt_connection, msg_id);
        break;
      case MQTT_MSG_TYPE_PUBCOMP:
        if(state->pending_msg_type == MQTT_MSG_TYPE_PUBLISH && state->pending_msg_id == msg_id)
          complete_pending(state, MQTT_EVENT_TYPE_PUBLISHED);
        break;
      case MQTT_MSG_TYPE_PINGREQ:
        state->outbound_message = mqtt_msg_pingresp(&state->mqtt_connection);
        break;
      case MQTT_MSG_TYPE_PINGRESP:
        // Ignore
        break;
    }

    // NOTE: this is done down here and not in the switch case above
    //       because the PSOCK_READBUF_LEN() won't work inside a switch
    //       statement due to the way protothreads resume.
    if(msg_type == MQTT_MSG_TYPE_PUBLISH)
    {
      uint16_t len;

      // adjust message_length and message_length_read so that
      // they only account for the publish data and not the rest of the 
      // message, this is done so that the offset passed with the
      // continuation event is the offset within the publish data and
      // not the offset within the message as a whole.
      len = state->message_length_read;
      mqtt_get_publish_data(state->in_buffer, &len);
      len = state->message_length_read - len;
      state->message_length -= len;
      state->message_length_read -= len;

      while(state->message_length_read < state->message_length)
      {
        PSOCK_READBUF_LEN(&state->ps, state->message_length - state->message_length_read);
        deliver_publish_continuation(state, state->message_length_read, state->in_buffer, PSOCK_DATALEN(&state->ps));
        state->message_length_read += PSOCK_DATALEN(&state->ps);
      }
    }
  }

  PSOCK_END(&state->ps);
}