37 #include "contiki-net.h" 
   40 #include "webclient.h" 
   42 #define WEBCLIENT_TIMEOUT 100 
   44 #define WEBCLIENT_STATE_STATUSLINE 0 
   45 #define WEBCLIENT_STATE_HEADERS    1 
   46 #define WEBCLIENT_STATE_DATA       2 
   47 #define WEBCLIENT_STATE_CLOSE      3 
   49 #define HTTPFLAG_NONE   0 
   51 #define HTTPFLAG_MOVED  2 
   52 #define HTTPFLAG_ERROR  3 
   57 #define ISO_space    0x20 
   59 struct webclient_state {
 
   66   char file[WWW_CONF_MAX_URLLEN];
 
   67   uint16_t getrequestptr;
 
   68   uint16_t getrequestleft;
 
   70   char httpheaderline[200];
 
   71   uint16_t httpheaderlineptr;
 
   76 static struct webclient_state s;
 
   80 webclient_mimetype(
void)
 
   86 webclient_filename(
void)
 
   92 webclient_hostname(
void)
 
  110 init_connection(
void)
 
  112   s.state = WEBCLIENT_STATE_STATUSLINE;
 
  114   s.getrequestleft = 
sizeof(http_get) - 1 + 1 +
 
  115     sizeof(http_10) - 1 +
 
  116     sizeof(http_crnl) - 1 +
 
  117     sizeof(http_host) - 1 +
 
  118     sizeof(http_crnl) - 1 +
 
  119     (uint16_t)strlen(http_user_agent_fields) +
 
  120     (uint16_t)strlen(s.file) + (uint16_t)strlen(s.host);
 
  123   s.httpheaderlineptr = 0;
 
  127 webclient_close(
void)
 
  129   s.state = WEBCLIENT_STATE_CLOSE;
 
  133 webclient_get(
const char *host, uint16_t port, 
const char *file)
 
  137   uip_ipaddr_t *ipaddr;
 
  158   strncpy(s.file, file, 
sizeof(s.file));
 
  159   strncpy(s.host, host, 
sizeof(s.host));
 
  170 static unsigned char *windowptr;
 
  171 static int windowstart, windowend;
 
  173 window_copy(
int curptr, 
const char *data, 
unsigned char datalen)
 
  177   if(windowstart == windowend) {
 
  178     return curptr + datalen;
 
  181   if(curptr + datalen < windowstart) {
 
  184     return curptr + datalen;
 
  187   if(curptr > windowend) {
 
  189     return curptr + datalen;
 
  195   data += windowstart - curptr;
 
  196   len  -= windowstart - curptr;
 
  199   if(len > windowend - windowstart) {
 
  200     len = windowend - windowstart;
 
  203   strncpy(windowptr + windowstart, data, len);
 
  206   return curptr + datalen;
 
  215   if(s.getrequestleft > 0) {
 
  217     windowstart = s.getrequestptr;
 
  219     windowend = windowstart + 
uip_mss();
 
  222     curptr = window_copy(curptr, http_get, 
sizeof(http_get) - 1);
 
  223     curptr = window_copy(curptr, s.file, (
unsigned char)strlen(s.file));
 
  224     curptr = window_copy(curptr, 
" ", 1);
 
  225     curptr = window_copy(curptr, http_10, 
sizeof(http_10) - 1);
 
  227     curptr = window_copy(curptr, http_crnl, 
sizeof(http_crnl) - 1);
 
  229     curptr = window_copy(curptr, http_host, 
sizeof(http_host) - 1);
 
  230     curptr = window_copy(curptr, s.host, (
unsigned char)strlen(s.host));
 
  231     curptr = window_copy(curptr, http_crnl, 
sizeof(http_crnl) - 1);
 
  233     curptr = window_copy(curptr, http_user_agent_fields,
 
  234                        (
unsigned char)strlen(http_user_agent_fields));
 
  236     len = s.getrequestleft > 
uip_mss()?
 
  248   if(s.getrequestleft > 0) {
 
  249     len = s.getrequestleft > 
uip_mss()?
 
  252     s.getrequestleft -= 
len;
 
  253     s.getrequestptr += 
len;
 
  258 parse_statusline(uint16_t len)
 
  262   while(len > 0 && s.httpheaderlineptr < 
sizeof(s.httpheaderline)) {
 
  263     s.httpheaderline[s.httpheaderlineptr] = *(
char *)
uip_appdata;
 
  266     if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
 
  268       if((strncmp(s.httpheaderline, http_10,
 
  269                   sizeof(http_10) - 1) == 0) ||
 
  270          (strncmp(s.httpheaderline, http_11,
 
  271                   sizeof(http_11) - 1) == 0)) {
 
  272         cptr = &(s.httpheaderline[9]);
 
  273         s.httpflag = HTTPFLAG_NONE;
 
  274         if(strncmp(cptr, http_200, 
sizeof(http_200) - 1) == 0) {
 
  276           s.httpflag = HTTPFLAG_OK;
 
  277         } 
else if(strncmp(cptr, http_301, 
sizeof(http_301) - 1) == 0 ||
 
  278                   strncmp(cptr, http_302, 
sizeof(http_302) - 1) == 0) {
 
  281           s.httpflag = HTTPFLAG_MOVED;
 
  283           s.httpheaderline[s.httpheaderlineptr - 1] = 0;
 
  293       s.httpheaderlineptr = 0;
 
  294       s.state = WEBCLIENT_STATE_HEADERS;
 
  297       ++s.httpheaderlineptr;
 
  304 casecmp(
char *str1, 
const char *str2, 
char len)
 
  325 parse_headers(uint16_t len)
 
  328   static unsigned char i;
 
  330   while(len > 0 && s.httpheaderlineptr < 
sizeof(s.httpheaderline)) {
 
  331     s.httpheaderline[s.httpheaderlineptr] = *(
char *)
uip_appdata;
 
  334     if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
 
  337       if(s.httpheaderline[0] == ISO_cr) {
 
  341         s.state = WEBCLIENT_STATE_DATA;
 
  345       s.httpheaderline[s.httpheaderlineptr - 1] = 0;
 
  347       if(casecmp(s.httpheaderline, http_content_type,
 
  348                      sizeof(http_content_type) - 1) == 0) {
 
  350         cptr = strchr(s.httpheaderline, 
';');
 
  354         strncpy(s.mimetype, s.httpheaderline +
 
  355                 sizeof(http_content_type) - 1, 
sizeof(s.mimetype));
 
  356       } 
else if(casecmp(s.httpheaderline, http_location,
 
  357                             sizeof(http_location) - 1) == 0) {
 
  358         cptr = s.httpheaderline +
 
  359           sizeof(http_location) - 1;
 
  361         if(strncmp(cptr, http_http, 7) == 0) {
 
  363           for(i = 0; i < s.httpheaderlineptr - 7; ++i) {
 
  375         strncpy(s.file, cptr, 
sizeof(s.file));
 
  382       s.httpheaderlineptr = 0;
 
  384       ++s.httpheaderlineptr;
 
  397   if(s.state == WEBCLIENT_STATE_STATUSLINE) {
 
  398     len = parse_statusline(len);
 
  401   if(s.state == WEBCLIENT_STATE_HEADERS && len > 0) {
 
  402     len = parse_headers(len);
 
  405   if(len > 0 && s.state == WEBCLIENT_STATE_DATA &&
 
  406      s.httpflag != HTTPFLAG_MOVED) {
 
  412 webclient_appcall(
void *state)
 
  418     s.state = WEBCLIENT_STATE_STATUSLINE;
 
  420     webclient_connected();
 
  426     webclient_timedout();
 
  438   if(s.state == WEBCLIENT_STATE_CLOSE) {
 
  467     if(s.timer == WEBCLIENT_TIMEOUT) {
 
  468       webclient_timedout();
 
  477     if(s.httpflag != HTTPFLAG_MOVED) {
 
  479       webclient_datahandler(
NULL, 0);
 
  488         resolv_query(s.host);
 
  491       webclient_get(s.host, s.port, s.file);
 
Hostname is fresh and usable. 
 
Representation of a uIP TCP connection. 
 
CCIF struct uip_conn * tcp_connect(uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Open a TCP connection to the specified IP address and port. 
 
#define uip_aborted()
Has the connection been aborted by the other end? 
 
CCIF void uip_send(const void *data, int len)
Send data on the current connection. 
 
#define uip_newdata()
Is new incoming data available? 
 
#define uip_mss()
Get the current maximum segment size that can be sent on the current connection. 
 
#define NULL
The null pointer. 
 
uint16_t len
Length of the data that was previously sent. 
 
#define uip_poll()
Is the connection being polled by uIP? 
 
#define uiplib_ipaddrconv
Convert a textual representation of an IP address to a numerical representation. 
 
#define uip_acked()
Has previously sent data been acknowledged? 
 
#define uip_connected()
Has the connection just been connected? 
 
#define uip_abort()
Abort the current connection. 
 
CCIF uint16_t uip_htons(uint16_t val)
Convert a 16-bit quantity from host byte order to network byte order. 
 
#define uip_datalen()
The length of any incoming data that is currently available (if available) in the uip_appdata buffer...
 
#define uip_timedout()
Has the connection timed out? 
 
#define uip_closed()
Has the connection been closed by the other end? 
 
uip_appdata
Pointer to the application data in the packet buffer. 
 
#define uip_rexmit()
Do we need to retransmit previously data?