00001 /* ---------------------------------------------------------------------------- 00002 * SAM Software Package License 00003 * ---------------------------------------------------------------------------- 00004 * Copyright (c) 2015, Atmel Corporation 00005 * 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions are met: 00010 * 00011 * - Redistributions of source code must retain the above copyright notice, 00012 * this list of conditions and the disclaimer below. 00013 * 00014 * Atmel's name may not be used to endorse or promote products derived from 00015 * this software without specific prior written permission. 00016 * 00017 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 00018 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00019 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 00020 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 00021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00022 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 00023 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00024 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00025 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 00026 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 * ---------------------------------------------------------------------------- 00028 */ 00029 00030 00031 /* lwIP Demo */ 00032 /* A simple HTTP/1.0 server directly interfacing the stack. */ 00033 00034 #include <board.h> 00035 #include <liblwip.h> 00036 00037 #include "lwip/opt.h" 00038 #include "lwip/tcp.h" 00039 00040 #include "httpd.h" 00041 00042 #define COUNTER_DISP_INDEX 119 00043 00044 /* This is the data for the actual web page. */ 00045 static char indexdata[] = 00046 "HTTP/1.1 200 OK\r\n\ 00047 Content-type: text/html\r\n\ 00048 \r\n\ 00049 <html> \ 00050 <head><title>lwIP test page</title></head> \ 00051 <body> \ 00052 Small test page. \ 00053 </body> \ 00054 </html>"; 00055 00056 /** 00057 * This is the callback function that is called 00058 * when a TCP segment has arrived in the connection. 00059 */ 00060 static err_t 00061 httpd_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) 00062 { 00063 char *rq; 00064 arg = arg; 00065 00066 //printf("CB recv %x, %x, %x, %x\n\r", arg, pcb, p, err); 00067 if (err != ERR_OK) 00068 return err; 00069 00070 /* If we got a NULL pbuf in p, the remote end has closed 00071 the connection. */ 00072 if (p != NULL) { 00073 00074 /* The payload pointer in the pbuf contains the data 00075 in the TCP segment. */ 00076 rq = p->payload; 00077 00078 /* Check if the request was an HTTP "GET /\r\n". 00079 or HTTP "GET / HTTP/1.1\r\n" */ 00080 if (rq[0] == 'G' && rq[1] == 'E' && rq[2] == 'T' && 00081 rq[3] == ' ' && rq[4] == '/' && 00082 ((rq[ 5] == '\r' && rq[ 6] == '\n') || 00083 (rq[14] == '\r' && rq[15] == '\n')) ) { 00084 /* Send the web page to the remote host. A zero 00085 in the last argument means that the data should 00086 not be copied into internal buffers. */ 00087 00088 tcp_write(pcb, indexdata, sizeof(indexdata), 0); 00089 } 00090 00091 /* Free the pbuf. */ 00092 pbuf_free(p); 00093 } 00094 00095 /* Close the connection. */ 00096 tcp_close(pcb); 00097 00098 return ERR_OK; 00099 } 00100 00101 /** 00102 * This is the callback function that is called when 00103 * a connection has been accepted. 00104 */ 00105 static err_t 00106 httpd_accept(void *arg, struct tcp_pcb *pcb, err_t err) 00107 { 00108 arg = arg; 00109 00110 if (err != ERR_OK) 00111 return err; 00112 00113 /* Set up the function httpd_recv() to be called when data 00114 arrives. */ 00115 tcp_recv(pcb, httpd_recv); 00116 return ERR_OK; 00117 } 00118 00119 /** 00120 * The initialization function. 00121 */ 00122 err_t 00123 httpd_init(void) 00124 { 00125 struct tcp_pcb *pcb; 00126 err_t err; 00127 /* Create a new TCP PCB. */ 00128 pcb = tcp_new(); 00129 00130 if (pcb == NULL) { 00131 printf("F: Fail to create PCB\n\r"); 00132 return ERR_BUF; 00133 } 00134 00135 /* Bind the PCB to TCP port 80. */ 00136 err = tcp_bind(pcb, NULL, 80); 00137 00138 if (err != ERR_OK) { 00139 printf("E: tcp_bind %x\n\r", err); 00140 return err; 00141 } 00142 00143 /* Change TCP state to LISTEN. */ 00144 pcb = tcp_listen(pcb); 00145 00146 if (pcb == NULL) { 00147 printf("E: tcp_listen\n\r"); 00148 return ERR_BUF; 00149 } 00150 00151 /* Set up httpd_accet() function to be called 00152 when a new connection arrives. */ 00153 tcp_accept(pcb, httpd_accept); 00154 00155 return ERR_OK; 00156 } 00157