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:39:45 2013 +0000
Revision:
99:1c92cc810ecb
Parent:
94:7bdeb5f4d111
Child:
125:96003ae6f1d8
Issue #44 fixed.

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
daniele 29:1a47b7151851 30 #include "EthernetInterface.h"
daniele 29:1a47b7151851 31 #include "Queue.h"
daniele 29:1a47b7151851 32 #include "wrapper.h"
daniele 29:1a47b7151851 33 #include "proxy_endpoint.h"
daniele 29:1a47b7151851 34 #include "pico_dev_mbed_emac.h"
daniele 29:1a47b7151851 35 #include "mbed.h"
daniele 29:1a47b7151851 36 #include "PicoCondition.h"
daniele 29:1a47b7151851 37 extern "C"{
daniele 29:1a47b7151851 38 #include "pico_stack.h"
daniele 29:1a47b7151851 39 #include "pico_config.h"
daniele 29:1a47b7151851 40 #include "cmsis_os.h"
daniele 29:1a47b7151851 41 #include "pico_dhcp_client.h"
daniele 29:1a47b7151851 42 #include "pico_dns_client.h"
daniele 29:1a47b7151851 43
tass 44:ffd9a11d4f95 44 //#define eth_dbg mbed_dbg
tass 42:13e557b44f68 45 #define eth_dbg(...)
tass 42:13e557b44f68 46
daniele 29:1a47b7151851 47 void (*linkCb)(uint32_t link) = NULL;
daniele 29:1a47b7151851 48 }
daniele 29:1a47b7151851 49
daniele 29:1a47b7151851 50 //DigitalOutput led(LED3);
daniele 29:1a47b7151851 51 /* TCP/IP and Network Interface Initialisation */
daniele 29:1a47b7151851 52 static struct pico_device *lpc_eth;
daniele 29:1a47b7151851 53
daniele 29:1a47b7151851 54 static uint32_t dhcp_xid = 0;
daniele 29:1a47b7151851 55 static PicoCondition dhcp_mx;
daniele 29:1a47b7151851 56 static int dhcp_retval = -1;
daniele 29:1a47b7151851 57
daniele 29:1a47b7151851 58 static char mac_addr[19];
daniele 29:1a47b7151851 59 static char ip_addr[17] = "\0";
daniele 29:1a47b7151851 60 static char gw_addr[17] = "\0";
daniele 29:1a47b7151851 61 static bool use_dhcp = false;
daniele 29:1a47b7151851 62 static bool is_initialized = false;
daniele 29:1a47b7151851 63
daniele 29:1a47b7151851 64 static void dhcp_cb(void *cli, int code)
daniele 29:1a47b7151851 65 {
daniele 29:1a47b7151851 66 void *id = NULL;
daniele 29:1a47b7151851 67 struct pico_ip4 address, gateway, zero = {};
tass 41:4c18c62b31b9 68
tass 42:13e557b44f68 69 if (PICO_DHCP_ERROR == code)
daniele 29:1a47b7151851 70 goto fail;
tass 99:1c92cc810ecb 71
tass 99:1c92cc810ecb 72 if (PICO_DHCP_RESET == code)
tass 99:1c92cc810ecb 73 goto reset;
tass 99:1c92cc810ecb 74
daniele 29:1a47b7151851 75 id = pico_dhcp_get_identifier(dhcp_xid);
daniele 29:1a47b7151851 76 if (!id)
daniele 29:1a47b7151851 77 goto fail;
daniele 29:1a47b7151851 78 address = pico_dhcp_get_address(id);
daniele 29:1a47b7151851 79 gateway = pico_dhcp_get_gateway(id);
daniele 29:1a47b7151851 80 //if (address) ? // still needed
daniele 29:1a47b7151851 81 pico_ipv4_to_string(ip_addr, address.addr);
tass 53:f3ea2e39a7b2 82 eth_dbg("IP assigned : %s\n",ip_addr);
daniele 29:1a47b7151851 83
daniele 29:1a47b7151851 84 if (gateway.addr != 0) {
daniele 29:1a47b7151851 85 pico_ipv4_to_string(gw_addr, gateway.addr);
tass 53:f3ea2e39a7b2 86 eth_dbg("Default gateway assigned : %s\n",gw_addr);
daniele 29:1a47b7151851 87 pico_ipv4_route_add(zero, zero, gateway, 1, NULL);
daniele 29:1a47b7151851 88 }
tass 43:5f2146814b83 89
tass 43:5f2146814b83 90 dhcp_retval = 0;
daniele 29:1a47b7151851 91 dhcp_mx.unlock();
tass 41:4c18c62b31b9 92
daniele 29:1a47b7151851 93 return;
daniele 29:1a47b7151851 94
daniele 29:1a47b7151851 95 fail:
tass 42:13e557b44f68 96 eth_dbg("DHCP request failed!\n");
daniele 29:1a47b7151851 97 dhcp_retval = -1;
daniele 29:1a47b7151851 98 dhcp_mx.unlock();
tass 99:1c92cc810ecb 99
tass 99:1c92cc810ecb 100 reset:
tass 99:1c92cc810ecb 101 eth_dbg("DHCP reset!\n");
daniele 29:1a47b7151851 102 }
daniele 29:1a47b7151851 103
daniele 29:1a47b7151851 104 static void init_eth(void)
daniele 29:1a47b7151851 105 {
daniele 29:1a47b7151851 106 if (!is_initialized) {
daniele 29:1a47b7151851 107 pico_stack_init();
daniele 29:1a47b7151851 108 picotcp_init();
daniele 29:1a47b7151851 109 lpc_eth = pico_emac_create("mbed0");
daniele 29:1a47b7151851 110 is_initialized = true;
daniele 29:1a47b7151851 111 pico_dns_client_init();
daniele 29:1a47b7151851 112 }
daniele 29:1a47b7151851 113 if (lpc_eth) {
daniele 29:1a47b7151851 114 snprintf(mac_addr, 19, "%02X:%02X:%02X:%02X:%02X:%02X", lpc_eth->eth->mac.addr[0], lpc_eth->eth->mac.addr[1],
daniele 29:1a47b7151851 115 lpc_eth->eth->mac.addr[2], lpc_eth->eth->mac.addr[3], lpc_eth->eth->mac.addr[4], lpc_eth->eth->mac.addr[5]);
daniele 29:1a47b7151851 116 }
tass 41:4c18c62b31b9 117
tass 41:4c18c62b31b9 118 if(lpc_eth)
tass 42:13e557b44f68 119 eth_dbg("Ethernet initialized...\n");
tass 41:4c18c62b31b9 120 else
tass 42:13e557b44f68 121 eth_dbg("Failed to start Ethernet...\n");
tass 41:4c18c62b31b9 122
daniele 29:1a47b7151851 123 }
daniele 29:1a47b7151851 124
daniele 29:1a47b7151851 125 int EthernetInterface::init()
daniele 29:1a47b7151851 126 {
daniele 29:1a47b7151851 127 init_eth();
daniele 29:1a47b7151851 128 /* use dhcp to retrieve address and gateway. */
daniele 29:1a47b7151851 129 use_dhcp = true;
daniele 29:1a47b7151851 130 return 0;
daniele 29:1a47b7151851 131 }
daniele 29:1a47b7151851 132
daniele 29:1a47b7151851 133 int EthernetInterface::init(const char* ip, const char* mask, const char* gateway) {
daniele 29:1a47b7151851 134 pico_ip4 pico_addr, pico_netmask, pico_gw = {0}, zero = {0};
daniele 29:1a47b7151851 135
tass 94:7bdeb5f4d111 136 if(strcmp(ip,gateway) == 0)
tass 94:7bdeb5f4d111 137 return -1;
tass 94:7bdeb5f4d111 138
daniele 29:1a47b7151851 139 init_eth();
daniele 29:1a47b7151851 140
daniele 29:1a47b7151851 141 use_dhcp = false;
daniele 29:1a47b7151851 142 strcpy(ip_addr, ip);
daniele 29:1a47b7151851 143
daniele 29:1a47b7151851 144 pico_string_to_ipv4(ip, &pico_addr.addr);
daniele 29:1a47b7151851 145 pico_string_to_ipv4(mask, &pico_netmask.addr);
daniele 29:1a47b7151851 146 if (gateway) {
tass 94:7bdeb5f4d111 147 pico_string_to_ipv4(gateway, &pico_gw.addr);
daniele 29:1a47b7151851 148 }
daniele 29:1a47b7151851 149 pico_ipv4_link_add(lpc_eth, pico_addr, pico_netmask);
daniele 29:1a47b7151851 150
daniele 29:1a47b7151851 151 if (pico_gw.addr)
daniele 29:1a47b7151851 152 pico_ipv4_route_add(zero, zero, pico_gw, 1, NULL);
daniele 29:1a47b7151851 153
daniele 29:1a47b7151851 154 return 0;
daniele 29:1a47b7151851 155 }
daniele 29:1a47b7151851 156
daniele 29:1a47b7151851 157 int EthernetInterface::connect(unsigned int timeout_ms) {
tass 99:1c92cc810ecb 158 IGNORE_PARAMETER(timeout_ms);
daniele 29:1a47b7151851 159 //dhcp_mx.lock(); do we still need this ?
daniele 29:1a47b7151851 160 if (use_dhcp) {
daniele 29:1a47b7151851 161 if (pico_dhcp_initiate_negotiation(lpc_eth, &dhcp_cb, &dhcp_xid) < 0)
daniele 29:1a47b7151851 162 return -1;
daniele 29:1a47b7151851 163
tass 99:1c92cc810ecb 164 dhcp_mx.lock(); // wait for a sign
tass 99:1c92cc810ecb 165 //timeout_ms removed because rtos limit lock timeout to approximate 65 seconds.
tass 41:4c18c62b31b9 166
daniele 29:1a47b7151851 167 return dhcp_retval;
daniele 29:1a47b7151851 168
daniele 29:1a47b7151851 169 } else {
daniele 29:1a47b7151851 170 return 0;
daniele 29:1a47b7151851 171 }
daniele 29:1a47b7151851 172 }
daniele 29:1a47b7151851 173
daniele 29:1a47b7151851 174 int EthernetInterface::disconnect() {
daniele 29:1a47b7151851 175 if (use_dhcp) {
daniele 29:1a47b7151851 176 }
daniele 29:1a47b7151851 177 pico_device_destroy(lpc_eth);
daniele 29:1a47b7151851 178 lpc_eth = NULL;
daniele 29:1a47b7151851 179 return 0;
daniele 29:1a47b7151851 180 }
daniele 29:1a47b7151851 181
daniele 29:1a47b7151851 182 char* EthernetInterface::getMACAddress() {
daniele 29:1a47b7151851 183 return mac_addr;
daniele 29:1a47b7151851 184 }
daniele 29:1a47b7151851 185
daniele 29:1a47b7151851 186 char* EthernetInterface::getIPAddress() {
daniele 29:1a47b7151851 187 return ip_addr;
daniele 29:1a47b7151851 188 }
daniele 29:1a47b7151851 189
daniele 29:1a47b7151851 190 int EthernetInterface::registerLinkStatus(void (*cb)(uint32_t linkStatus))
daniele 29:1a47b7151851 191 {
daniele 29:1a47b7151851 192 ::linkCb = cb;
daniele 29:1a47b7151851 193 return 0;
daniele 29:1a47b7151851 194 }
daniele 29:1a47b7151851 195
daniele 29:1a47b7151851 196 int EthernetInterface::setDnsServer(const char * name)
daniele 29:1a47b7151851 197 {
daniele 29:1a47b7151851 198 struct pico_ip4 addr;
daniele 29:1a47b7151851 199 pico_string_to_ipv4(name,&addr.addr);
daniele 29:1a47b7151851 200 return pico_dns_client_nameserver(&addr,PICO_DNS_NS_ADD);
daniele 29:1a47b7151851 201 }