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:
Thu Jan 28 15:12:00 2016 +0100
Revision:
155:a70f34550c34
Parent:
142:35da43068894
Adding TCP flag for FIN.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
daniele 29:1a47b7151851 1 /*
daniele 29:1a47b7151851 2 *
daniele 29:1a47b7151851 3 * PicoTCP Socket interface for mbed.
daniele 29:1a47b7151851 4 * Copyright (C) 2013 TASS Belgium NV
daniele 29:1a47b7151851 5 *
daniele 29:1a47b7151851 6 * Released under GPL v2
daniele 29:1a47b7151851 7 *
daniele 29:1a47b7151851 8 * Other licensing models might apply at the sole discretion of the copyright holders.
daniele 29:1a47b7151851 9 *
daniele 29:1a47b7151851 10 *
daniele 29:1a47b7151851 11 * This software is based on the mbed.org EthernetInterface implementation:
daniele 29:1a47b7151851 12 * Copyright (C) 2012 mbed.org, MIT License
daniele 29:1a47b7151851 13 *
daniele 29:1a47b7151851 14 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
daniele 29:1a47b7151851 15 * and associated documentation files (the "Software"), to deal in the Software without restriction,
daniele 29:1a47b7151851 16 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
daniele 29:1a47b7151851 17 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
daniele 29:1a47b7151851 18 * furnished to do so, subject to the following conditions:
daniele 29:1a47b7151851 19 *
daniele 29:1a47b7151851 20 * The above copyright notice and this permission notice shall be included in all copies or
daniele 29:1a47b7151851 21 * substantial portions of the Software.
daniele 29:1a47b7151851 22 *
daniele 29:1a47b7151851 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
daniele 29:1a47b7151851 24 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
daniele 29:1a47b7151851 25 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
daniele 29:1a47b7151851 26 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
daniele 29:1a47b7151851 27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
daniele 29:1a47b7151851 28 */
daniele 29:1a47b7151851 29 #include "TCPSocketConnection.h"
daniele 29:1a47b7151851 30 #include "wrapper.h"
daniele 29:1a47b7151851 31 #include <cstring>
daniele 29:1a47b7151851 32
daniele 29:1a47b7151851 33 using std::memset;
daniele 29:1a47b7151851 34 using std::memcpy;
daniele 29:1a47b7151851 35
tass 53:f3ea2e39a7b2 36 TCPSocketConnection::TCPSocketConnection()
tass 53:f3ea2e39a7b2 37 {
daniele 29:1a47b7151851 38 }
daniele 29:1a47b7151851 39
daniele 29:1a47b7151851 40 int TCPSocketConnection::connect(const char* host, const int port) {
daniele 29:1a47b7151851 41 if (init_socket(SOCK_STREAM) < 0)
daniele 29:1a47b7151851 42 {
tass 44:ffd9a11d4f95 43 mbed_dbg("init_socket\n");
daniele 29:1a47b7151851 44 return -1;
daniele 29:1a47b7151851 45 }
tass 37:bdf736327c71 46
daniele 29:1a47b7151851 47 if (set_address(host, port) != 0)
daniele 29:1a47b7151851 48 {
tass 44:ffd9a11d4f95 49 mbed_dbg("set_address\n");
daniele 29:1a47b7151851 50 return -1;
daniele 29:1a47b7151851 51 }
daniele 29:1a47b7151851 52 if (picotcp_connect(_ep, (struct sockaddr *) &_remoteHost, sizeof(_remoteHost)) < 0) {
daniele 29:1a47b7151851 53 close();
daniele 29:1a47b7151851 54 return -1;
daniele 29:1a47b7151851 55 }
daniele 29:1a47b7151851 56
daniele 29:1a47b7151851 57 return 0;
daniele 29:1a47b7151851 58 }
daniele 29:1a47b7151851 59
daniele 29:1a47b7151851 60 bool TCPSocketConnection::is_connected(void) {
tass 53:f3ea2e39a7b2 61 if((_ep == NULL) || (_ep->state != SOCK_CONNECTED))
tass 53:f3ea2e39a7b2 62 return false;
tass 53:f3ea2e39a7b2 63 else
tass 53:f3ea2e39a7b2 64 return true;
daniele 29:1a47b7151851 65 }
daniele 29:1a47b7151851 66
daniele 29:1a47b7151851 67 int TCPSocketConnection::send(char* data, int length) {
daniele 29:1a47b7151851 68 int ret;
tass picotcp@tass.be 142:35da43068894 69 pico_time localTimeout = _timeout;
tass picotcp@tass.be 142:35da43068894 70 pico_time finalTimeout = PICO_TIME_MS() + _timeout;
tass 53:f3ea2e39a7b2 71 if (!is_connected())
daniele 29:1a47b7151851 72 return -1;
daniele 29:1a47b7151851 73
tass 39:8d4d653d94bd 74 if(is_writable())
tass 39:8d4d653d94bd 75 {
tass 39:8d4d653d94bd 76 ret = picotcp_write(_ep, data, length);
tass 39:8d4d653d94bd 77 if(ret < length)
tass 39:8d4d653d94bd 78 _ep->revents &= (~PICO_SOCK_EV_WR);
tass 39:8d4d653d94bd 79 if(ret) // data was read or error was reported
tass 39:8d4d653d94bd 80 return ret;
tass 39:8d4d653d94bd 81 }
tass 58:5f6eedbbbd5b 82 repeat:
tass 58:5f6eedbbbd5b 83 TimeInterval timeout(!_blocking ? localTimeout : osWaitForever);
tass 35:6078073547bb 84 if (wait_writable(timeout) != 0)
tass 35:6078073547bb 85 {
daniele 47:ed8f44fa8db9 86 return 0; /* Timeout */
daniele 29:1a47b7151851 87 }
tass 35:6078073547bb 88
daniele 29:1a47b7151851 89 ret = picotcp_write(_ep, data, length);
daniele 29:1a47b7151851 90 if (ret < length) {
daniele 29:1a47b7151851 91 _ep->revents &= (~PICO_SOCK_EV_WR);
tass 44:ffd9a11d4f95 92 //mbed_dbg("Short write\n");
tass 58:5f6eedbbbd5b 93 if(ret ==0 && pico_err == PICO_ERR_EAGAIN && PICO_TIME_MS() < finalTimeout)
tass 58:5f6eedbbbd5b 94 {
tass 58:5f6eedbbbd5b 95 localTimeout = finalTimeout - PICO_TIME_MS();
tass 58:5f6eedbbbd5b 96 goto repeat;
tass 58:5f6eedbbbd5b 97 }
daniele 29:1a47b7151851 98 }
daniele 29:1a47b7151851 99 return ret;
daniele 29:1a47b7151851 100 }
daniele 29:1a47b7151851 101
daniele 29:1a47b7151851 102 // -1 if unsuccessful, else number of bytes written
daniele 29:1a47b7151851 103 int TCPSocketConnection::send_all(char* data, int length) {
tass 39:8d4d653d94bd 104 return send(data,length);
daniele 29:1a47b7151851 105 }
daniele 29:1a47b7151851 106
daniele 29:1a47b7151851 107 int TCPSocketConnection::receive(char* data, int length) {
daniele 29:1a47b7151851 108 int ret;
tass 65:8cdaaa1df01d 109 if (!is_connected() && !is_readable())
daniele 29:1a47b7151851 110 return -1;
daniele 29:1a47b7151851 111
tass 39:8d4d653d94bd 112 if(is_readable())
tass 39:8d4d653d94bd 113 {
tass 39:8d4d653d94bd 114 ret = picotcp_read(_ep, data, length);
tass 39:8d4d653d94bd 115 if(ret<length)
tass 39:8d4d653d94bd 116 _ep->revents &= (~PICO_SOCK_EV_RD);
tass 39:8d4d653d94bd 117 if(ret) // data was read or error was reported
tass 39:8d4d653d94bd 118 return ret;
tass 39:8d4d653d94bd 119 }
tass 35:6078073547bb 120
tass 35:6078073547bb 121 TimeInterval timeout(!_blocking ? _timeout : osWaitForever);
tass 35:6078073547bb 122 if (wait_readable(timeout) != 0)
tass 35:6078073547bb 123 {
daniele 47:ed8f44fa8db9 124 return 0; /* Timeout */
daniele 29:1a47b7151851 125 }
tass 35:6078073547bb 126
daniele 29:1a47b7151851 127 ret = picotcp_read(_ep, data, length);
daniele 29:1a47b7151851 128 if (ret < length) {
daniele 29:1a47b7151851 129 _ep->revents &= (~PICO_SOCK_EV_RD);
tass 44:ffd9a11d4f95 130 //mbed_dbg("Short read\n");
daniele 29:1a47b7151851 131 }
daniele 29:1a47b7151851 132 return ret;
daniele 29:1a47b7151851 133 }
daniele 29:1a47b7151851 134
daniele 29:1a47b7151851 135 // -1 if unsuccessful, else number of bytes received
daniele 29:1a47b7151851 136 int TCPSocketConnection::receive_all(char* data, int length) {
daniele 29:1a47b7151851 137 return receive(data, length);
daniele 29:1a47b7151851 138 }