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:
daniele
Date:
Fri May 24 15:25:25 2013 +0000
Revision:
3:b4047e8a0123
Child:
51:ab4529a384a6
Updated from main repo + fixed Mutexes;

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