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 Oct 18 09:41:50 2013 +0000
Revision:
101:37763e3777a7
Parent:
68:0847e35d08a6
Child:
131:4758606c9316
merge with mainline Issue #39

Who changed what in which revision?

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