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

Fork of PicoTCP by Daniele Lacamera

Committer:
daniele
Date:
Sat Aug 03 08:50:27 2013 +0000
Revision:
51:18637a3d071f
Parent:
3:b4047e8a0123
Branch for CDC-ECM: Work in progress

Who changed what in which revision?

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