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

Dependents:   lpc1768-picotcp-demo ZeroMQ_PicoTCP_Publisher_demo TCPSocket_HelloWorld_PicoTCP Pico_TCP_UDP_Test ... more

PicoTCP. Copyright (c) 2013 TASS Belgium NV.

Released under the GNU General Public License, version 2.

Different licensing models may exist, at the sole discretion of the Copyright holders.

Official homepage: http://www.picotcp.com

Bug tracker: https://github.com/tass-belgium/picotcp/issues

Development steps:

  • initial integration with mbed RTOS
  • generic mbed Ethernet driver
  • high performance NXP LPC1768 specific Ethernet driver
  • Multi-threading support for mbed RTOS
  • Berkeley sockets and integration with the New Socket API
  • Fork of the apps running on top of the New Socket API
  • Scheduling optimizations
  • Debugging/benchmarking/testing

Demo application (measuring TCP sender performance):

Import programlpc1768-picotcp-demo

A PicoTCP demo app testing the ethernet throughput on the lpc1768 mbed board.

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