Free (GPLv2) TCP/IP stack developed by TASS Belgium

Fork of PicoTCP by Daniele Lacamera

Committer:
tass
Date:
Fri May 17 12:09:59 2013 +0000
Revision:
1:cfe8984a32b4
Parent:
libraries/picotcp/modules/pico_simple_http.c@0:d7f2341ab245
Update for smaller SOCKETQ

Who changed what in which revision?

UserRevisionLine numberNew contents of line
daniele 0:d7f2341ab245 1 /*********************************************************************
daniele 0:d7f2341ab245 2 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
daniele 0:d7f2341ab245 3 See LICENSE and COPYING for usage.
daniele 0:d7f2341ab245 4
daniele 0:d7f2341ab245 5 Author: Andrei Carp <andrei.carp@tass.be>
daniele 0:d7f2341ab245 6 *********************************************************************/
daniele 0:d7f2341ab245 7
daniele 0:d7f2341ab245 8 #include "pico_config.h"
daniele 0:d7f2341ab245 9 #include "pico_socket.h"
daniele 0:d7f2341ab245 10 #include "pico_tcp.h"
daniele 0:d7f2341ab245 11 #include "pico_ipv4.h"
daniele 0:d7f2341ab245 12 #include "pico_simple_http.h"
daniele 0:d7f2341ab245 13
daniele 0:d7f2341ab245 14 /* The HTTP Server cannot be available without TCP support */
daniele 0:d7f2341ab245 15 #if (defined PICO_SUPPORT_HTTP) && (defined PICO_SUPPORT_IPV4) && (defined PICO_SUPPORT_TCP)
daniele 0:d7f2341ab245 16
daniele 0:d7f2341ab245 17 #define HTTP_LISTEN_PORT 80u
daniele 0:d7f2341ab245 18 #define HTTP_BACKLOG 5u
daniele 0:d7f2341ab245 19 #define HTTP_HEADER_SIZE 256u
daniele 0:d7f2341ab245 20
daniele 0:d7f2341ab245 21 #define HTTP_SUCCESS 0
daniele 0:d7f2341ab245 22 #define HTTP_ERROR -1
daniele 0:d7f2341ab245 23
daniele 0:d7f2341ab245 24 static struct pico_socket * httpServer = NULL;
daniele 0:d7f2341ab245 25 static char httpResponse[] =
daniele 0:d7f2341ab245 26 "HTTP/1.0 200 OK\r\n\
daniele 0:d7f2341ab245 27 Content-Type: text/html\r\n\
daniele 0:d7f2341ab245 28 \r\n\
daniele 0:d7f2341ab245 29 <html><head>\r\n\
daniele 0:d7f2341ab245 30 <title>picoTCP Simple Http server</title>\r\n\
daniele 0:d7f2341ab245 31 </head>\r\n\
daniele 0:d7f2341ab245 32 <body>\r\n\
daniele 0:d7f2341ab245 33 <h1>Hello world from picoTCP !!</h1>\r\n\
daniele 0:d7f2341ab245 34 </body>\r\n";
daniele 0:d7f2341ab245 35
daniele 0:d7f2341ab245 36 static void httpEventCbk(uint16_t ev, struct pico_socket *self)
daniele 0:d7f2341ab245 37 {
daniele 0:d7f2341ab245 38 static struct pico_socket * client = NULL;
daniele 0:d7f2341ab245 39 uint32_t peer;
daniele 0:d7f2341ab245 40 uint16_t port;
daniele 0:d7f2341ab245 41 int r;
daniele 0:d7f2341ab245 42 char buffer[HTTP_HEADER_SIZE];
daniele 0:d7f2341ab245 43
daniele 0:d7f2341ab245 44 switch(ev)
daniele 0:d7f2341ab245 45 {
daniele 0:d7f2341ab245 46 case PICO_SOCK_EV_CONN :
daniele 0:d7f2341ab245 47 if(!client)
daniele 0:d7f2341ab245 48 client = pico_socket_accept(self, &peer, &port);
daniele 0:d7f2341ab245 49 break;
daniele 0:d7f2341ab245 50
daniele 0:d7f2341ab245 51 case PICO_SOCK_EV_RD:
daniele 0:d7f2341ab245 52 // do not check http integrity, just mark that the http header has arrived
daniele 0:d7f2341ab245 53 // prepare to send the response
daniele 0:d7f2341ab245 54 r = pico_socket_recvfrom(self, buffer, HTTP_HEADER_SIZE, &peer, &port);
daniele 0:d7f2341ab245 55 if(r>0 && memcmp(buffer,"GET",3u) == 0u)
daniele 0:d7f2341ab245 56 { // it is an http header asking for data, return data and close
daniele 0:d7f2341ab245 57 pico_socket_write(self,httpResponse,sizeof(httpResponse));
daniele 0:d7f2341ab245 58 pico_socket_close(self);
daniele 0:d7f2341ab245 59 }
daniele 0:d7f2341ab245 60 else
daniele 0:d7f2341ab245 61 {
daniele 0:d7f2341ab245 62 // kill the connection, invalid header
daniele 0:d7f2341ab245 63 pico_socket_close(self);
daniele 0:d7f2341ab245 64 }
daniele 0:d7f2341ab245 65 break;
daniele 0:d7f2341ab245 66
daniele 0:d7f2341ab245 67 case PICO_SOCK_EV_ERR:
daniele 0:d7f2341ab245 68 case PICO_SOCK_EV_CLOSE:
daniele 0:d7f2341ab245 69 // free the used socket
daniele 0:d7f2341ab245 70 client = NULL;
daniele 0:d7f2341ab245 71 break;
daniele 0:d7f2341ab245 72
daniele 0:d7f2341ab245 73 default :
daniele 0:d7f2341ab245 74 break;
daniele 0:d7f2341ab245 75 }
daniele 0:d7f2341ab245 76 }
daniele 0:d7f2341ab245 77
daniele 0:d7f2341ab245 78 int pico_startHttpServer(struct pico_ip4 * address)
daniele 0:d7f2341ab245 79 {
daniele 0:d7f2341ab245 80
daniele 0:d7f2341ab245 81 uint16_t localHttpPort = short_be(HTTP_LISTEN_PORT);
daniele 0:d7f2341ab245 82
daniele 0:d7f2341ab245 83 if(!pico_is_port_free(localHttpPort,PICO_PROTO_TCP, address, &pico_proto_ipv4))
daniele 0:d7f2341ab245 84 {
daniele 0:d7f2341ab245 85 pico_err = PICO_ERR_EADDRINUSE;
daniele 0:d7f2341ab245 86 return HTTP_ERROR;
daniele 0:d7f2341ab245 87 }
daniele 0:d7f2341ab245 88
daniele 0:d7f2341ab245 89 httpServer = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, httpEventCbk);
daniele 0:d7f2341ab245 90
daniele 0:d7f2341ab245 91 if(!httpServer)
daniele 0:d7f2341ab245 92 {
daniele 0:d7f2341ab245 93 pico_err = PICO_ERR_ENOMEM;
daniele 0:d7f2341ab245 94 return HTTP_ERROR;
daniele 0:d7f2341ab245 95 }
daniele 0:d7f2341ab245 96
daniele 0:d7f2341ab245 97 // both functions set the pico_err themselves.
daniele 0:d7f2341ab245 98 if(pico_socket_bind(httpServer,address,&localHttpPort))
daniele 0:d7f2341ab245 99 return HTTP_ERROR;
daniele 0:d7f2341ab245 100
daniele 0:d7f2341ab245 101 if(pico_socket_listen(httpServer,HTTP_BACKLOG))
daniele 0:d7f2341ab245 102 return HTTP_ERROR;
daniele 0:d7f2341ab245 103
daniele 0:d7f2341ab245 104 return HTTP_SUCCESS;
daniele 0:d7f2341ab245 105 }
daniele 0:d7f2341ab245 106
daniele 0:d7f2341ab245 107 int pico_stopHttpServer(void)
daniele 0:d7f2341ab245 108 {
daniele 0:d7f2341ab245 109 if(!httpServer)
daniele 0:d7f2341ab245 110 {
daniele 0:d7f2341ab245 111 pico_err = PICO_ERR_EINVAL;
daniele 0:d7f2341ab245 112 return HTTP_ERROR;
daniele 0:d7f2341ab245 113 }
daniele 0:d7f2341ab245 114
daniele 0:d7f2341ab245 115 if(pico_socket_close(httpServer))
daniele 0:d7f2341ab245 116 {
daniele 0:d7f2341ab245 117 // no need to set the error here, function already set it
daniele 0:d7f2341ab245 118 httpServer = NULL;
daniele 0:d7f2341ab245 119 return HTTP_ERROR;
daniele 0:d7f2341ab245 120 }
daniele 0:d7f2341ab245 121
daniele 0:d7f2341ab245 122 httpServer = NULL;
daniele 0:d7f2341ab245 123 return HTTP_SUCCESS;
daniele 0:d7f2341ab245 124 }
daniele 0:d7f2341ab245 125
daniele 0:d7f2341ab245 126 #endif
daniele 0:d7f2341ab245 127
daniele 0:d7f2341ab245 128