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:
Mon Sep 02 08:02:21 2013 +0000
Revision:
51:ab4529a384a6
Parent:
3:b4047e8a0123
Updated from masterbranch

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
tass 51:ab4529a384a6 17 #define HTTP_LISTEN_PORT 80u
tass 51:ab4529a384a6 18 #define HTTP_BACKLOG 5u
daniele 3:b4047e8a0123 19 #define HTTP_HEADER_SIZE 256u
daniele 3:b4047e8a0123 20
tass 51:ab4529a384a6 21 #define HTTP_SUCCESS 0
tass 51:ab4529a384a6 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 {
tass 51:ab4529a384a6 38 static struct pico_socket * client = NULL;
tass 51:ab4529a384a6 39 uint32_t peer;
tass 51:ab4529a384a6 40 uint16_t port;
tass 51:ab4529a384a6 41 int r;
tass 51:ab4529a384a6 42 char buffer[HTTP_HEADER_SIZE];
daniele 3:b4047e8a0123 43
tass 51:ab4529a384a6 44 switch(ev)
tass 51:ab4529a384a6 45 {
tass 51:ab4529a384a6 46 case PICO_SOCK_EV_CONN :
tass 51:ab4529a384a6 47 if(!client)
tass 51:ab4529a384a6 48 client = pico_socket_accept(self, &peer, &port);
tass 51:ab4529a384a6 49 break;
daniele 3:b4047e8a0123 50
tass 51:ab4529a384a6 51 case PICO_SOCK_EV_RD:
tass 51:ab4529a384a6 52 // do not check http integrity, just mark that the http header has arrived
tass 51:ab4529a384a6 53 // prepare to send the response
tass 51:ab4529a384a6 54 r = pico_socket_recvfrom(self, buffer, HTTP_HEADER_SIZE, &peer, &port);
tass 51:ab4529a384a6 55 if(r>0 && memcmp(buffer,"GET",3u) == 0u)
tass 51:ab4529a384a6 56 { // it is an http header asking for data, return data and close
tass 51:ab4529a384a6 57 pico_socket_write(self,httpResponse,sizeof(httpResponse));
tass 51:ab4529a384a6 58 pico_socket_close(self);
tass 51:ab4529a384a6 59 }
tass 51:ab4529a384a6 60 else
tass 51:ab4529a384a6 61 {
tass 51:ab4529a384a6 62 // kill the connection, invalid header
tass 51:ab4529a384a6 63 pico_socket_close(self);
tass 51:ab4529a384a6 64 }
tass 51:ab4529a384a6 65 break;
daniele 3:b4047e8a0123 66
tass 51:ab4529a384a6 67 case PICO_SOCK_EV_ERR:
tass 51:ab4529a384a6 68 case PICO_SOCK_EV_CLOSE:
tass 51:ab4529a384a6 69 // free the used socket
tass 51:ab4529a384a6 70 client = NULL;
tass 51:ab4529a384a6 71 break;
daniele 3:b4047e8a0123 72
tass 51:ab4529a384a6 73 default :
tass 51:ab4529a384a6 74 break;
tass 51:ab4529a384a6 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
tass 51:ab4529a384a6 81 uint16_t localHttpPort = short_be(HTTP_LISTEN_PORT);
daniele 3:b4047e8a0123 82
tass 51:ab4529a384a6 83 if(!pico_is_port_free(localHttpPort,PICO_PROTO_TCP, address, &pico_proto_ipv4))
tass 51:ab4529a384a6 84 {
tass 51:ab4529a384a6 85 pico_err = PICO_ERR_EADDRINUSE;
tass 51:ab4529a384a6 86 return HTTP_ERROR;
tass 51:ab4529a384a6 87 }
daniele 3:b4047e8a0123 88
tass 51:ab4529a384a6 89 httpServer = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, httpEventCbk);
daniele 3:b4047e8a0123 90
tass 51:ab4529a384a6 91 if(!httpServer)
tass 51:ab4529a384a6 92 {
tass 51:ab4529a384a6 93 pico_err = PICO_ERR_ENOMEM;
tass 51:ab4529a384a6 94 return HTTP_ERROR;
tass 51:ab4529a384a6 95 }
daniele 3:b4047e8a0123 96
tass 51:ab4529a384a6 97 // both functions set the pico_err themselves.
tass 51:ab4529a384a6 98 if(pico_socket_bind(httpServer,address,&localHttpPort))
tass 51:ab4529a384a6 99 return HTTP_ERROR;
daniele 3:b4047e8a0123 100
tass 51:ab4529a384a6 101 if(pico_socket_listen(httpServer,HTTP_BACKLOG))
tass 51:ab4529a384a6 102 return HTTP_ERROR;
daniele 3:b4047e8a0123 103
tass 51:ab4529a384a6 104 return HTTP_SUCCESS;
daniele 3:b4047e8a0123 105 }
daniele 3:b4047e8a0123 106
daniele 3:b4047e8a0123 107 int pico_stopHttpServer(void)
daniele 3:b4047e8a0123 108 {
tass 51:ab4529a384a6 109 if(!httpServer)
tass 51:ab4529a384a6 110 {
tass 51:ab4529a384a6 111 pico_err = PICO_ERR_EINVAL;
tass 51:ab4529a384a6 112 return HTTP_ERROR;
tass 51:ab4529a384a6 113 }
daniele 3:b4047e8a0123 114
tass 51:ab4529a384a6 115 if(pico_socket_close(httpServer))
tass 51:ab4529a384a6 116 {
tass 51:ab4529a384a6 117 // no need to set the error here, function already set it
tass 51:ab4529a384a6 118 httpServer = NULL;
tass 51:ab4529a384a6 119 return HTTP_ERROR;
tass 51:ab4529a384a6 120 }
daniele 3:b4047e8a0123 121
tass 51:ab4529a384a6 122 httpServer = NULL;
tass 51:ab4529a384a6 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