Mbed library for ENC28J60 Ethernet modules. Full support for TCP/IP and UDP Server, Client and HTTP server (webserver). DHCP and DNS is included.

Dependents:   mBuino_ENC28_MQTT Nucleo_Web_ENC28J60 Nucleo_Web_ENC28J60_ADC Serial_over_Ethernet ... more

Library for ENC28J60 Ethernet modules.

/media/uploads/hudakz/enc28j60_module01.jpg

Ported to mbed from Norbert Truchsess's UIPEthernet library for Arduino. Thank you Norbert!

  • Full support for persistent (streaming) TCP/IP and UDP connections Client and Server each, ARP, ICMP, DHCP and DNS.
  • Works with both Mbed OS 2 and Mbed OS 5.

Usage:

  • Import the library into your project.
  • Add #include "UipEthernet.h" to main.cpp
  • Create one instance of the UipEthernet class initialized with the MAC address you'd like to use and SPI pins of the connected Mbed board.

Example programs:

Import programWebSwitch_ENC28J60

HTTP Server serving a simple webpage which enables to remotely turn a digital output on/off. Compile, download, run and type 'IP_address/secret/' (don't forget the last '/') into your web browser and hit ENTER.

Import programHTTPServer_Echo_ENC28J60

A simple HTTP server echoing received requests. Ethernet connection is over an ENC28J60 board. Usage: Type the server's IP address into you web browser and hit <ENTER>.

Import programTcpServer_ENC28J60

Simple TCP/IP Server using the UIPEthernet library for ENC28J60 Ethernet boards.

Import programTcpClient_ENC28J60

Simple TCP/IP Client using the UIPEthernet library for ENC28J60 Ethernet boards.

Import programUdpServer_ENC28J60

Simple UDP Server using the UIPEthernet library for ENC28J60 Ethernet boards.

Import programUdpClient_ENC28J60

Simple UDP Client using the UIPEthernet library for ENC28J60 Ethernet boards.

Import programMQTT_Hello_ENC28J60

MQTT Client example program. Ethernet connection is via an ENC28J60 module.

Committer:
hudakz
Date:
Tue Aug 27 15:01:10 2019 +0000
Revision:
9:a156d3de5647
Child:
11:647d53d146f1
Mbed OS 5 support added and API modified.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 9:a156d3de5647 1 /*
hudakz 9:a156d3de5647 2 UIPEthernet.cpp - Arduino implementation of a UIP wrapper class.
hudakz 9:a156d3de5647 3 Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
hudakz 9:a156d3de5647 4 All rights reserved.
hudakz 9:a156d3de5647 5
hudakz 9:a156d3de5647 6 Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.com>
hudakz 9:a156d3de5647 7
hudakz 9:a156d3de5647 8 This program is free software: you can redistribute it and/or modify
hudakz 9:a156d3de5647 9 it under the terms of the GNU General Public License as published by
hudakz 9:a156d3de5647 10 the Free Software Foundation, either version 3 of the License, or
hudakz 9:a156d3de5647 11 (at your option) any later version.
hudakz 9:a156d3de5647 12
hudakz 9:a156d3de5647 13 This program is distributed in the hope that it will be useful,
hudakz 9:a156d3de5647 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
hudakz 9:a156d3de5647 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
hudakz 9:a156d3de5647 16 GNU General Public License for more details.
hudakz 9:a156d3de5647 17
hudakz 9:a156d3de5647 18 You should have received a copy of the GNU General Public License
hudakz 9:a156d3de5647 19 along with this program. If not, see <http://www.gnu.org/licenses/>.
hudakz 9:a156d3de5647 20 */
hudakz 9:a156d3de5647 21 #include "mbed.h"
hudakz 9:a156d3de5647 22 #include "UipEthernet.h"
hudakz 9:a156d3de5647 23 #include "utility/Enc28j60Py.h"
hudakz 9:a156d3de5647 24 #include "UdpSocket.h"
hudakz 9:a156d3de5647 25
hudakz 9:a156d3de5647 26 extern "C"
hudakz 9:a156d3de5647 27 {
hudakz 9:a156d3de5647 28 #include "utility/uip-conf.h"
hudakz 9:a156d3de5647 29 #include "utility/uip.h"
hudakz 9:a156d3de5647 30 #include "utility/uip_arp.h"
hudakz 9:a156d3de5647 31 #include "utility/uip_timer.h"
hudakz 9:a156d3de5647 32 }
hudakz 9:a156d3de5647 33 #define ETH_HDR ((struct uip_eth_hdr*) &uip_buf[0])
hudakz 9:a156d3de5647 34
hudakz 9:a156d3de5647 35 UipEthernet* UipEthernet:: ethernet = NULL;
hudakz 9:a156d3de5647 36 memhandle UipEthernet:: inPacket(NOBLOCK);
hudakz 9:a156d3de5647 37 memhandle UipEthernet:: uipPacket(NOBLOCK);
hudakz 9:a156d3de5647 38 uint8_t UipEthernet:: uipHeaderLen(0);
hudakz 9:a156d3de5647 39 uint8_t UipEthernet:: packetState(0);
hudakz 9:a156d3de5647 40 IpAddress UipEthernet:: dnsServerAddress;
hudakz 9:a156d3de5647 41 //DhcpClient UIPEthernet:: dhcpClient;
hudakz 9:a156d3de5647 42
hudakz 9:a156d3de5647 43 /**
hudakz 9:a156d3de5647 44 * @brief
hudakz 9:a156d3de5647 45 * @note
hudakz 9:a156d3de5647 46 * @param
hudakz 9:a156d3de5647 47 * @retval
hudakz 9:a156d3de5647 48 */
hudakz 9:a156d3de5647 49 void enc28j60_mempool_block_move_callback(memaddress dest, memaddress src, memaddress len)
hudakz 9:a156d3de5647 50 {
hudakz 9:a156d3de5647 51 //as ENC28J60 DMA is unable to copy single bytes:
hudakz 9:a156d3de5647 52 if (len == 1) {
hudakz 9:a156d3de5647 53 UipEthernet::ethernet->phy.writeByte(dest, UipEthernet::ethernet->phy.readByte(src));
hudakz 9:a156d3de5647 54 }
hudakz 9:a156d3de5647 55 else {
hudakz 9:a156d3de5647 56 // calculate address of last byte
hudakz 9:a156d3de5647 57 len += src - 1;
hudakz 9:a156d3de5647 58
hudakz 9:a156d3de5647 59 /* 1. Appropriately program the EDMAST, EDMAND
hudakz 9:a156d3de5647 60 and EDMADST register pairs. The EDMAST
hudakz 9:a156d3de5647 61 registers should point to the first byte to copy
hudakz 9:a156d3de5647 62 from, the EDMAND registers should point to the
hudakz 9:a156d3de5647 63 last byte to copy and the EDMADST registers
hudakz 9:a156d3de5647 64 should point to the first byte in the destination
hudakz 9:a156d3de5647 65 range. The destination range will always be
hudakz 9:a156d3de5647 66 linear, never wrapping at any values except from
hudakz 9:a156d3de5647 67 8191 to 0 (the 8-Kbyte memory boundary).
hudakz 9:a156d3de5647 68 Extreme care should be taken when
hudakz 9:a156d3de5647 69 programming the start and end pointers to
hudakz 9:a156d3de5647 70 prevent a never ending DMA operation which
hudakz 9:a156d3de5647 71 would overwrite the entire 8-Kbyte buffer.
hudakz 9:a156d3de5647 72 */
hudakz 9:a156d3de5647 73 UipEthernet::ethernet->phy.writeRegPair(EDMASTL, src);
hudakz 9:a156d3de5647 74 UipEthernet::ethernet->phy.writeRegPair(EDMADSTL, dest);
hudakz 9:a156d3de5647 75
hudakz 9:a156d3de5647 76 if ((src <= RXSTOP_INIT) && (len > RXSTOP_INIT))
hudakz 9:a156d3de5647 77 len -= (RXSTOP_INIT - RXSTART_INIT);
hudakz 9:a156d3de5647 78 UipEthernet::ethernet->phy.writeRegPair(EDMANDL, len);
hudakz 9:a156d3de5647 79
hudakz 9:a156d3de5647 80 /* 2. If an interrupt at the end of the copy process is
hudakz 9:a156d3de5647 81 desired, set EIE.DMAIE and EIE.INTIE and
hudakz 9:a156d3de5647 82 clear EIR.DMAIF.
hudakz 9:a156d3de5647 83
hudakz 9:a156d3de5647 84 3. Verify that ECON1.CSUMEN is clear. */
hudakz 9:a156d3de5647 85 UipEthernet::ethernet->phy.writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN);
hudakz 9:a156d3de5647 86
hudakz 9:a156d3de5647 87 /* 4. Start the DMA copy by setting ECON1.DMAST. */
hudakz 9:a156d3de5647 88 UipEthernet::ethernet->phy.writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);
hudakz 9:a156d3de5647 89
hudakz 9:a156d3de5647 90 // wait until runnig DMA is completed
hudakz 9:a156d3de5647 91 while (UipEthernet::ethernet->phy.readOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_DMAST);
hudakz 9:a156d3de5647 92 }
hudakz 9:a156d3de5647 93 }
hudakz 9:a156d3de5647 94
hudakz 9:a156d3de5647 95 /*
hudakz 9:a156d3de5647 96 * Because UIP isn't encapsulated within a class we have to use global
hudakz 9:a156d3de5647 97 * variables, so we can only have one TCP/IP stack per program.
hudakz 9:a156d3de5647 98 */
hudakz 9:a156d3de5647 99 UipEthernet::UipEthernet(const uint8_t mac[6], PinName mosi, PinName miso, PinName sck, PinName cs) :
hudakz 9:a156d3de5647 100 phy(mosi, miso, sck, cs),
hudakz 9:a156d3de5647 101 _mac(new uint8_t[6]),
hudakz 9:a156d3de5647 102 _ip(),
hudakz 9:a156d3de5647 103 _dns(),
hudakz 9:a156d3de5647 104 _gateway(),
hudakz 9:a156d3de5647 105 _subnet()
hudakz 9:a156d3de5647 106 {
hudakz 9:a156d3de5647 107 for (uint8_t i = 0; i < 6; i++)
hudakz 9:a156d3de5647 108 _mac[i] = mac[i];
hudakz 9:a156d3de5647 109 }
hudakz 9:a156d3de5647 110
hudakz 9:a156d3de5647 111 #if UIP_UDP
hudakz 9:a156d3de5647 112
hudakz 9:a156d3de5647 113 /**
hudakz 9:a156d3de5647 114 * @brief
hudakz 9:a156d3de5647 115 * @note
hudakz 9:a156d3de5647 116 * @param
hudakz 9:a156d3de5647 117 * @retval
hudakz 9:a156d3de5647 118 */
hudakz 9:a156d3de5647 119 int UipEthernet::connect()
hudakz 9:a156d3de5647 120 {
hudakz 9:a156d3de5647 121 // Inicialize static pointer to the UIPEthernet instance
hudakz 9:a156d3de5647 122 ethernet = this;
hudakz 9:a156d3de5647 123
hudakz 9:a156d3de5647 124 // Initialise the basic info
hudakz 9:a156d3de5647 125 init(_mac);
hudakz 9:a156d3de5647 126
hudakz 9:a156d3de5647 127 // If no local IP address has been set ask DHCP server to provide one
hudakz 9:a156d3de5647 128 if (_ip == IpAddress()) {
hudakz 9:a156d3de5647 129 // Now try to get our config info from a DHCP server
hudakz 9:a156d3de5647 130 int ret = dhcpClient.begin((uint8_t*)_mac);
hudakz 9:a156d3de5647 131
hudakz 9:a156d3de5647 132 if (ret == 1) {
hudakz 9:a156d3de5647 133 // We've successfully found a DHCP server and got our configuration info, so set things
hudakz 9:a156d3de5647 134 // accordingly
hudakz 9:a156d3de5647 135 set_network
hudakz 9:a156d3de5647 136 (
hudakz 9:a156d3de5647 137 dhcpClient.getLocalIp(),
hudakz 9:a156d3de5647 138 dhcpClient.getDnsServerIp(),
hudakz 9:a156d3de5647 139 dhcpClient.getGatewayIp(),
hudakz 9:a156d3de5647 140 dhcpClient.getSubnetMask()
hudakz 9:a156d3de5647 141 );
hudakz 9:a156d3de5647 142 }
hudakz 9:a156d3de5647 143
hudakz 9:a156d3de5647 144 return ret;
hudakz 9:a156d3de5647 145 }
hudakz 9:a156d3de5647 146 else {
hudakz 9:a156d3de5647 147 return 1;
hudakz 9:a156d3de5647 148 }
hudakz 9:a156d3de5647 149 }
hudakz 9:a156d3de5647 150 #endif
hudakz 9:a156d3de5647 151
hudakz 9:a156d3de5647 152 /**
hudakz 9:a156d3de5647 153 * @brief
hudakz 9:a156d3de5647 154 * @note
hudakz 9:a156d3de5647 155 * @param
hudakz 9:a156d3de5647 156 * @retval
hudakz 9:a156d3de5647 157 */
hudakz 9:a156d3de5647 158 void UipEthernet::set_network(uint8_t octet1, uint8_t octet2, uint8_t octet3, uint8_t octet4)
hudakz 9:a156d3de5647 159 {
hudakz 9:a156d3de5647 160 _ip = IpAddress(octet1, octet2, octet3, octet4);
hudakz 9:a156d3de5647 161 set_network(_ip);
hudakz 9:a156d3de5647 162 }
hudakz 9:a156d3de5647 163
hudakz 9:a156d3de5647 164 /**
hudakz 9:a156d3de5647 165 * @brief
hudakz 9:a156d3de5647 166 * @note
hudakz 9:a156d3de5647 167 * @param
hudakz 9:a156d3de5647 168 * @retval
hudakz 9:a156d3de5647 169 */
hudakz 9:a156d3de5647 170 void UipEthernet::set_network(IpAddress ip)
hudakz 9:a156d3de5647 171 {
hudakz 9:a156d3de5647 172 _ip = ip;
hudakz 9:a156d3de5647 173 _dns = ip;
hudakz 9:a156d3de5647 174 _dns[3] = 1;
hudakz 9:a156d3de5647 175 set_network(ip, dns);
hudakz 9:a156d3de5647 176 }
hudakz 9:a156d3de5647 177
hudakz 9:a156d3de5647 178 /**
hudakz 9:a156d3de5647 179 * @brief
hudakz 9:a156d3de5647 180 * @note
hudakz 9:a156d3de5647 181 * @param
hudakz 9:a156d3de5647 182 * @retval
hudakz 9:a156d3de5647 183 */
hudakz 9:a156d3de5647 184 void UipEthernet::set_network(IpAddress ip, IpAddress dns)
hudakz 9:a156d3de5647 185 {
hudakz 9:a156d3de5647 186 _ip = ip;
hudakz 9:a156d3de5647 187 _dns = dns;
hudakz 9:a156d3de5647 188 _gateway = ip;
hudakz 9:a156d3de5647 189 _gateway[3] = 1;
hudakz 9:a156d3de5647 190 set_network(ip, dns, _gateway);
hudakz 9:a156d3de5647 191 }
hudakz 9:a156d3de5647 192
hudakz 9:a156d3de5647 193 /**
hudakz 9:a156d3de5647 194 * @brief
hudakz 9:a156d3de5647 195 * @note
hudakz 9:a156d3de5647 196 * @param
hudakz 9:a156d3de5647 197 * @retval
hudakz 9:a156d3de5647 198 */
hudakz 9:a156d3de5647 199 void UipEthernet::set_network(IpAddress ip, IpAddress dns, IpAddress gateway)
hudakz 9:a156d3de5647 200 {
hudakz 9:a156d3de5647 201 _ip = ip;
hudakz 9:a156d3de5647 202 _dns = dns;
hudakz 9:a156d3de5647 203 _gateway = gateway;
hudakz 9:a156d3de5647 204 _subnet = IpAddress(255, 255, 255, 0);
hudakz 9:a156d3de5647 205 }
hudakz 9:a156d3de5647 206
hudakz 9:a156d3de5647 207 /**
hudakz 9:a156d3de5647 208 * @brief
hudakz 9:a156d3de5647 209 * @note
hudakz 9:a156d3de5647 210 * @param
hudakz 9:a156d3de5647 211 * @retval
hudakz 9:a156d3de5647 212 */
hudakz 9:a156d3de5647 213 void UipEthernet::set_network(IpAddress ip, IpAddress dns, IpAddress gateway, IpAddress subnet)
hudakz 9:a156d3de5647 214 {
hudakz 9:a156d3de5647 215 uip_ipaddr_t ipaddr;
hudakz 9:a156d3de5647 216
hudakz 9:a156d3de5647 217 uip_ip_addr(ipaddr, ip);
hudakz 9:a156d3de5647 218 uip_sethostaddr(ipaddr);
hudakz 9:a156d3de5647 219
hudakz 9:a156d3de5647 220 uip_ip_addr(ipaddr, gateway);
hudakz 9:a156d3de5647 221 uip_setdraddr(ipaddr);
hudakz 9:a156d3de5647 222
hudakz 9:a156d3de5647 223 uip_ip_addr(ipaddr, subnet);
hudakz 9:a156d3de5647 224 uip_setnetmask(ipaddr);
hudakz 9:a156d3de5647 225
hudakz 9:a156d3de5647 226 dnsServerAddress = dns;
hudakz 9:a156d3de5647 227 }
hudakz 9:a156d3de5647 228
hudakz 9:a156d3de5647 229 /**
hudakz 9:a156d3de5647 230 * @brief
hudakz 9:a156d3de5647 231 * @note
hudakz 9:a156d3de5647 232 * @param
hudakz 9:a156d3de5647 233 * @retval
hudakz 9:a156d3de5647 234 */
hudakz 9:a156d3de5647 235 IpAddress UipEthernet::localIP()
hudakz 9:a156d3de5647 236 {
hudakz 9:a156d3de5647 237 uip_ipaddr_t a;
hudakz 9:a156d3de5647 238
hudakz 9:a156d3de5647 239 uip_gethostaddr(a);
hudakz 9:a156d3de5647 240 return ip_addr_uip(a);
hudakz 9:a156d3de5647 241 }
hudakz 9:a156d3de5647 242
hudakz 9:a156d3de5647 243 /**
hudakz 9:a156d3de5647 244 * @brief
hudakz 9:a156d3de5647 245 * @note
hudakz 9:a156d3de5647 246 * @param
hudakz 9:a156d3de5647 247 * @retval
hudakz 9:a156d3de5647 248 */
hudakz 9:a156d3de5647 249 IpAddress UipEthernet::subnetMask()
hudakz 9:a156d3de5647 250 {
hudakz 9:a156d3de5647 251 uip_ipaddr_t a;
hudakz 9:a156d3de5647 252
hudakz 9:a156d3de5647 253 uip_getnetmask(a);
hudakz 9:a156d3de5647 254 return ip_addr_uip(a);
hudakz 9:a156d3de5647 255 }
hudakz 9:a156d3de5647 256
hudakz 9:a156d3de5647 257 /**
hudakz 9:a156d3de5647 258 * @brief
hudakz 9:a156d3de5647 259 * @note
hudakz 9:a156d3de5647 260 * @param
hudakz 9:a156d3de5647 261 * @retval
hudakz 9:a156d3de5647 262 */
hudakz 9:a156d3de5647 263 IpAddress UipEthernet::gatewayIP()
hudakz 9:a156d3de5647 264 {
hudakz 9:a156d3de5647 265 uip_ipaddr_t a;
hudakz 9:a156d3de5647 266
hudakz 9:a156d3de5647 267 uip_getdraddr(a);
hudakz 9:a156d3de5647 268 return ip_addr_uip(a);
hudakz 9:a156d3de5647 269 }
hudakz 9:a156d3de5647 270
hudakz 9:a156d3de5647 271 /**
hudakz 9:a156d3de5647 272 * @brief
hudakz 9:a156d3de5647 273 * @note
hudakz 9:a156d3de5647 274 * @param
hudakz 9:a156d3de5647 275 * @retval
hudakz 9:a156d3de5647 276 */
hudakz 9:a156d3de5647 277 IpAddress UipEthernet::dnsServerIP()
hudakz 9:a156d3de5647 278 {
hudakz 9:a156d3de5647 279 return dnsServerAddress;
hudakz 9:a156d3de5647 280 }
hudakz 9:a156d3de5647 281
hudakz 9:a156d3de5647 282 /**
hudakz 9:a156d3de5647 283 * @brief
hudakz 9:a156d3de5647 284 * @note
hudakz 9:a156d3de5647 285 * @param
hudakz 9:a156d3de5647 286 * @retval
hudakz 9:a156d3de5647 287 */
hudakz 9:a156d3de5647 288 const char* UipEthernet::get_ip_address()
hudakz 9:a156d3de5647 289 {
hudakz 9:a156d3de5647 290 static char buf[16];
hudakz 9:a156d3de5647 291 return localIP().toString(buf);
hudakz 9:a156d3de5647 292 }
hudakz 9:a156d3de5647 293
hudakz 9:a156d3de5647 294 /**
hudakz 9:a156d3de5647 295 * @brief
hudakz 9:a156d3de5647 296 * @note
hudakz 9:a156d3de5647 297 * @param
hudakz 9:a156d3de5647 298 * @retval
hudakz 9:a156d3de5647 299 */
hudakz 9:a156d3de5647 300 const char* UipEthernet::get_netmask()
hudakz 9:a156d3de5647 301 {
hudakz 9:a156d3de5647 302 static char buf[16];
hudakz 9:a156d3de5647 303 return subnetMask().toString(buf);
hudakz 9:a156d3de5647 304 }
hudakz 9:a156d3de5647 305
hudakz 9:a156d3de5647 306 /**
hudakz 9:a156d3de5647 307 * @brief
hudakz 9:a156d3de5647 308 * @note
hudakz 9:a156d3de5647 309 * @param
hudakz 9:a156d3de5647 310 * @retval
hudakz 9:a156d3de5647 311 */
hudakz 9:a156d3de5647 312 const char* UipEthernet::get_gateway()
hudakz 9:a156d3de5647 313 {
hudakz 9:a156d3de5647 314 static char buf[16];
hudakz 9:a156d3de5647 315 return gatewayIP().toString(buf);
hudakz 9:a156d3de5647 316 }
hudakz 9:a156d3de5647 317
hudakz 9:a156d3de5647 318 /**
hudakz 9:a156d3de5647 319 * @brief
hudakz 9:a156d3de5647 320 * @note
hudakz 9:a156d3de5647 321 * @param
hudakz 9:a156d3de5647 322 * @retval
hudakz 9:a156d3de5647 323 */
hudakz 9:a156d3de5647 324 void UipEthernet::tick()
hudakz 9:a156d3de5647 325 {
hudakz 9:a156d3de5647 326 if (inPacket == NOBLOCK) {
hudakz 9:a156d3de5647 327 inPacket = phy.receivePacket();
hudakz 9:a156d3de5647 328 #ifdef UIPETHERNET_DEBUG
hudakz 9:a156d3de5647 329 if (in_packet != NOBLOCK) {
hudakz 9:a156d3de5647 330 printf("--------------\r\nreceivePacket: %d\r\n", in_packet);
hudakz 9:a156d3de5647 331 }
hudakz 9:a156d3de5647 332 #endif
hudakz 9:a156d3de5647 333 }
hudakz 9:a156d3de5647 334
hudakz 9:a156d3de5647 335 if (inPacket != NOBLOCK) {
hudakz 9:a156d3de5647 336 packetState = UIPETHERNET_FREEPACKET;
hudakz 9:a156d3de5647 337 uip_len = phy.blockSize(inPacket);
hudakz 9:a156d3de5647 338 if (uip_len > 0) {
hudakz 9:a156d3de5647 339 phy.readPacket(inPacket, 0, (uint8_t*)uip_buf, UIP_BUFSIZE);
hudakz 9:a156d3de5647 340 if (ETH_HDR->type == HTONS(UIP_ETHTYPE_IP)) {
hudakz 9:a156d3de5647 341 uipPacket = inPacket; //required for upper_layer_checksum of in_packet!
hudakz 9:a156d3de5647 342 #ifdef UIPETHERNET_DEBUG
hudakz 9:a156d3de5647 343 printf("readPacket type IP, uip_len: %d\r\n", uip_len);
hudakz 9:a156d3de5647 344 #endif
hudakz 9:a156d3de5647 345 uip_arp_ipin();
hudakz 9:a156d3de5647 346 uip_input();
hudakz 9:a156d3de5647 347 if (uip_len > 0) {
hudakz 9:a156d3de5647 348 uip_arp_out();
hudakz 9:a156d3de5647 349 network_send();
hudakz 9:a156d3de5647 350 }
hudakz 9:a156d3de5647 351 }
hudakz 9:a156d3de5647 352 else
hudakz 9:a156d3de5647 353 if (ETH_HDR->type == HTONS(UIP_ETHTYPE_ARP))
hudakz 9:a156d3de5647 354 {
hudakz 9:a156d3de5647 355 #ifdef UIPETHERNET_DEBUG
hudakz 9:a156d3de5647 356 printf("readPacket type ARP, uip_len: %d\r\n", uip_len);
hudakz 9:a156d3de5647 357 #endif
hudakz 9:a156d3de5647 358 uip_arp_arpin();
hudakz 9:a156d3de5647 359 if (uip_len > 0) {
hudakz 9:a156d3de5647 360 network_send();
hudakz 9:a156d3de5647 361 }
hudakz 9:a156d3de5647 362 }
hudakz 9:a156d3de5647 363 }
hudakz 9:a156d3de5647 364
hudakz 9:a156d3de5647 365 if (inPacket != NOBLOCK && (packetState & UIPETHERNET_FREEPACKET))
hudakz 9:a156d3de5647 366 {
hudakz 9:a156d3de5647 367 #ifdef UIPETHERNET_DEBUG
hudakz 9:a156d3de5647 368 printf("freeing packet: %d\r\n", in_packet);
hudakz 9:a156d3de5647 369 #endif
hudakz 9:a156d3de5647 370 phy.freePacket();
hudakz 9:a156d3de5647 371 inPacket = NOBLOCK;
hudakz 9:a156d3de5647 372 }
hudakz 9:a156d3de5647 373 }
hudakz 9:a156d3de5647 374
hudakz 9:a156d3de5647 375 bool periodic = periodicTimer.read_ms() > UIP_PERIODIC_TIMEOUT;
hudakz 9:a156d3de5647 376
hudakz 9:a156d3de5647 377 for (int i = 0; i < UIP_CONNS; i++) {
hudakz 9:a156d3de5647 378 uip_conn = &uip_conns[i];
hudakz 9:a156d3de5647 379 if (periodic) {
hudakz 9:a156d3de5647 380 uip_process(UIP_TIMER);
hudakz 9:a156d3de5647 381 }
hudakz 9:a156d3de5647 382 else {
hudakz 9:a156d3de5647 383 uip_userdata_t* data = (uip_userdata_t*)uip_conn->appstate;
hudakz 9:a156d3de5647 384 if (data != NULL) {
hudakz 9:a156d3de5647 385 if (data->pollTimer.read_ms() >= UIP_CLIENT_TIMEOUT) {
hudakz 9:a156d3de5647 386 uip_process(UIP_POLL_REQUEST);
hudakz 9:a156d3de5647 387 data->pollTimer.stop();
hudakz 9:a156d3de5647 388 data->pollTimer.reset();
hudakz 9:a156d3de5647 389 }
hudakz 9:a156d3de5647 390 }
hudakz 9:a156d3de5647 391 else
hudakz 9:a156d3de5647 392 continue;
hudakz 9:a156d3de5647 393 }
hudakz 9:a156d3de5647 394
hudakz 9:a156d3de5647 395 // If the above function invocation resulted in data that
hudakz 9:a156d3de5647 396 // should be sent out on the Enc28J60Network, the global variable
hudakz 9:a156d3de5647 397 // uip_len is set to a value > 0.
hudakz 9:a156d3de5647 398 if (uip_len > 0) {
hudakz 9:a156d3de5647 399 uip_arp_out();
hudakz 9:a156d3de5647 400 network_send();
hudakz 9:a156d3de5647 401 }
hudakz 9:a156d3de5647 402 }
hudakz 9:a156d3de5647 403
hudakz 9:a156d3de5647 404 if (periodic) {
hudakz 9:a156d3de5647 405 periodicTimer.reset();
hudakz 9:a156d3de5647 406 #if UIP_UDP
hudakz 9:a156d3de5647 407 for (int i = 0; i < UIP_UDP_CONNS; i++) {
hudakz 9:a156d3de5647 408 uip_udp_periodic(i);
hudakz 9:a156d3de5647 409
hudakz 9:a156d3de5647 410 // If the above function invocation resulted in data that
hudakz 9:a156d3de5647 411 // should be sent out on the Enc28J60Network, the global variable
hudakz 9:a156d3de5647 412 // uip_len is set to a value > 0.
hudakz 9:a156d3de5647 413 if (uip_len > 0) {
hudakz 9:a156d3de5647 414 UdpSocket::_send((uip_udp_userdata_t *) (uip_udp_conns[i].appstate));
hudakz 9:a156d3de5647 415 }
hudakz 9:a156d3de5647 416 }
hudakz 9:a156d3de5647 417 #endif // UIP_UDP
hudakz 9:a156d3de5647 418 }
hudakz 9:a156d3de5647 419 }
hudakz 9:a156d3de5647 420
hudakz 9:a156d3de5647 421 /**
hudakz 9:a156d3de5647 422 * @brief
hudakz 9:a156d3de5647 423 * @note
hudakz 9:a156d3de5647 424 * @param
hudakz 9:a156d3de5647 425 * @retval
hudakz 9:a156d3de5647 426 */
hudakz 9:a156d3de5647 427 bool UipEthernet::network_send()
hudakz 9:a156d3de5647 428 {
hudakz 9:a156d3de5647 429 if (packetState & UIPETHERNET_SENDPACKET)
hudakz 9:a156d3de5647 430 {
hudakz 9:a156d3de5647 431 #ifdef UIPETHERNET_DEBUG
hudakz 9:a156d3de5647 432 printf("Enc28J60Network_send uip_packet: %d, hdrlen: %d\r\n", uip_packet, uip_hdrlen);
hudakz 9:a156d3de5647 433 #endif
hudakz 9:a156d3de5647 434 phy.writePacket(uipPacket, 0, uip_buf, uipHeaderLen);
hudakz 9:a156d3de5647 435 packetState &= ~UIPETHERNET_SENDPACKET;
hudakz 9:a156d3de5647 436 goto sendandfree;
hudakz 9:a156d3de5647 437 }
hudakz 9:a156d3de5647 438
hudakz 9:a156d3de5647 439 uipPacket = Enc28j60Phy::allocBlock(uip_len);
hudakz 9:a156d3de5647 440 if (uipPacket != NOBLOCK)
hudakz 9:a156d3de5647 441 {
hudakz 9:a156d3de5647 442 #ifdef UIPETHERNET_DEBUG
hudakz 9:a156d3de5647 443 printf("Enc28J60Network_send uip_buf (uip_len): %d, packet: %d\r\n", uip_len, uip_packet);
hudakz 9:a156d3de5647 444 #endif
hudakz 9:a156d3de5647 445 phy.writePacket(uipPacket, 0, uip_buf, uip_len);
hudakz 9:a156d3de5647 446 goto sendandfree;
hudakz 9:a156d3de5647 447 }
hudakz 9:a156d3de5647 448
hudakz 9:a156d3de5647 449 return false;
hudakz 9:a156d3de5647 450 sendandfree:
hudakz 9:a156d3de5647 451 phy.sendPacket(uipPacket);
hudakz 9:a156d3de5647 452 Enc28j60Phy::freeBlock(uipPacket);
hudakz 9:a156d3de5647 453 uipPacket = NOBLOCK;
hudakz 9:a156d3de5647 454 return true;
hudakz 9:a156d3de5647 455 }
hudakz 9:a156d3de5647 456
hudakz 9:a156d3de5647 457 /**
hudakz 9:a156d3de5647 458 * @brief
hudakz 9:a156d3de5647 459 * @note
hudakz 9:a156d3de5647 460 * @param
hudakz 9:a156d3de5647 461 * @retval
hudakz 9:a156d3de5647 462 */
hudakz 9:a156d3de5647 463 void UipEthernet::init(const uint8_t* mac)
hudakz 9:a156d3de5647 464 {
hudakz 9:a156d3de5647 465 periodicTimer.start();
hudakz 9:a156d3de5647 466
hudakz 9:a156d3de5647 467 phy.init((uint8_t*)mac);
hudakz 9:a156d3de5647 468 uip_seteth_addr(mac);
hudakz 9:a156d3de5647 469
hudakz 9:a156d3de5647 470 uip_init();
hudakz 9:a156d3de5647 471 uip_arp_init();
hudakz 9:a156d3de5647 472 }
hudakz 9:a156d3de5647 473
hudakz 9:a156d3de5647 474 /**
hudakz 9:a156d3de5647 475 * @brief
hudakz 9:a156d3de5647 476 * @note
hudakz 9:a156d3de5647 477 * @param
hudakz 9:a156d3de5647 478 * @retval
hudakz 9:a156d3de5647 479 */
hudakz 9:a156d3de5647 480 //void UIPEthernet::configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet)
hudakz 9:a156d3de5647 481 //{
hudakz 9:a156d3de5647 482 // uip_ipaddr_t ipaddr;
hudakz 9:a156d3de5647 483 // uip_ip_addr(ipaddr, ip);
hudakz 9:a156d3de5647 484 // uip_sethostaddr(ipaddr);
hudakz 9:a156d3de5647 485 // uip_ip_addr(ipaddr, gateway);
hudakz 9:a156d3de5647 486 // uip_setdraddr(ipaddr);
hudakz 9:a156d3de5647 487 // uip_ip_addr(ipaddr, subnet);
hudakz 9:a156d3de5647 488 // uip_setnetmask(ipaddr);
hudakz 9:a156d3de5647 489 // dnsServerAddress = dns;
hudakz 9:a156d3de5647 490 //}
hudakz 9:a156d3de5647 491
hudakz 9:a156d3de5647 492 /**
hudakz 9:a156d3de5647 493 * @brief
hudakz 9:a156d3de5647 494 * @note
hudakz 9:a156d3de5647 495 * @param
hudakz 9:a156d3de5647 496 * @retval
hudakz 9:a156d3de5647 497 */
hudakz 9:a156d3de5647 498 uint16_t UipEthernet::chksum(uint16_t sum, const uint8_t* data, uint16_t len)
hudakz 9:a156d3de5647 499 {
hudakz 9:a156d3de5647 500 uint16_t t;
hudakz 9:a156d3de5647 501 const uint8_t* dataptr;
hudakz 9:a156d3de5647 502 const uint8_t* last_byte;
hudakz 9:a156d3de5647 503
hudakz 9:a156d3de5647 504 dataptr = data;
hudakz 9:a156d3de5647 505 last_byte = data + len - 1;
hudakz 9:a156d3de5647 506
hudakz 9:a156d3de5647 507 while (dataptr < last_byte) {
hudakz 9:a156d3de5647 508 /* At least two more bytes */
hudakz 9:a156d3de5647 509 t = (dataptr[0] << 8) + dataptr[1];
hudakz 9:a156d3de5647 510 sum += t;
hudakz 9:a156d3de5647 511 if (sum < t) {
hudakz 9:a156d3de5647 512 sum++; /* carry */
hudakz 9:a156d3de5647 513 }
hudakz 9:a156d3de5647 514
hudakz 9:a156d3de5647 515 dataptr += 2;
hudakz 9:a156d3de5647 516 }
hudakz 9:a156d3de5647 517
hudakz 9:a156d3de5647 518 if (dataptr == last_byte) {
hudakz 9:a156d3de5647 519 t = (dataptr[0] << 8) + 0;
hudakz 9:a156d3de5647 520 sum += t;
hudakz 9:a156d3de5647 521 if (sum < t) {
hudakz 9:a156d3de5647 522 sum++; /* carry */
hudakz 9:a156d3de5647 523 }
hudakz 9:a156d3de5647 524 }
hudakz 9:a156d3de5647 525
hudakz 9:a156d3de5647 526 /* Return sum in host byte order. */
hudakz 9:a156d3de5647 527 return sum;
hudakz 9:a156d3de5647 528 }
hudakz 9:a156d3de5647 529
hudakz 9:a156d3de5647 530 /**
hudakz 9:a156d3de5647 531 * @brief
hudakz 9:a156d3de5647 532 * @note
hudakz 9:a156d3de5647 533 * @param
hudakz 9:a156d3de5647 534 * @retval
hudakz 9:a156d3de5647 535 */
hudakz 9:a156d3de5647 536 uint16_t UipEthernet::ipchksum()
hudakz 9:a156d3de5647 537 {
hudakz 9:a156d3de5647 538 uint16_t sum;
hudakz 9:a156d3de5647 539
hudakz 9:a156d3de5647 540 sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
hudakz 9:a156d3de5647 541 return(sum == 0) ? 0xffff : htons(sum);
hudakz 9:a156d3de5647 542 }
hudakz 9:a156d3de5647 543
hudakz 9:a156d3de5647 544 uint16_t
hudakz 9:a156d3de5647 545 #if UIP_UDP
hudakz 9:a156d3de5647 546 UipEthernet::upper_layer_chksum(uint8_t proto)
hudakz 9:a156d3de5647 547 #else
hudakz 9:a156d3de5647 548 uip_tcpchksum()
hudakz 9:a156d3de5647 549 #endif
hudakz 9:a156d3de5647 550 {
hudakz 9:a156d3de5647 551 uint16_t upper_layer_len;
hudakz 9:a156d3de5647 552 uint16_t sum;
hudakz 9:a156d3de5647 553
hudakz 9:a156d3de5647 554 #if UIP_CONF_IPV6
hudakz 9:a156d3de5647 555 upper_layer_len = (((u16_t) (BUF->len[0]) << 8) + BUF->len[1]);
hudakz 9:a156d3de5647 556 #else /* UIP_CONF_IPV6 */
hudakz 9:a156d3de5647 557 upper_layer_len = (((u16_t) (BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
hudakz 9:a156d3de5647 558 #endif /* UIP_CONF_IPV6 */
hudakz 9:a156d3de5647 559
hudakz 9:a156d3de5647 560 /* First sum pseudoheader. */
hudakz 9:a156d3de5647 561
hudakz 9:a156d3de5647 562 /* IP protocol and length fields. This addition cannot carry. */
hudakz 9:a156d3de5647 563 #if UIP_UDP
hudakz 9:a156d3de5647 564 sum = upper_layer_len + proto;
hudakz 9:a156d3de5647 565 #else
hudakz 9:a156d3de5647 566 sum = upper_layer_len + UIP_PROTO_TCP;
hudakz 9:a156d3de5647 567 #endif
hudakz 9:a156d3de5647 568 /* Sum IP source and destination addresses. */
hudakz 9:a156d3de5647 569
hudakz 9:a156d3de5647 570 sum = UipEthernet::chksum(sum, (u8_t*) &BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t));
hudakz 9:a156d3de5647 571
hudakz 9:a156d3de5647 572 uint8_t upper_layer_memlen;
hudakz 9:a156d3de5647 573 #if UIP_UDP
hudakz 9:a156d3de5647 574 switch (proto) {
hudakz 9:a156d3de5647 575 // case UIP_PROTO_ICMP:
hudakz 9:a156d3de5647 576 // case UIP_PROTO_ICMP6:
hudakz 9:a156d3de5647 577 // upper_layer_memlen = upper_layer_len;
hudakz 9:a156d3de5647 578 // break;
hudakz 9:a156d3de5647 579 case UIP_PROTO_UDP:
hudakz 9:a156d3de5647 580 upper_layer_memlen = UIP_UDPH_LEN;
hudakz 9:a156d3de5647 581 break;
hudakz 9:a156d3de5647 582
hudakz 9:a156d3de5647 583 default:
hudakz 9:a156d3de5647 584 // case UIP_PROTO_TCP:
hudakz 9:a156d3de5647 585 #endif
hudakz 9:a156d3de5647 586 upper_layer_memlen = (BUF->tcpoffset >> 4) << 2;
hudakz 9:a156d3de5647 587 #if UIP_UDP
hudakz 9:a156d3de5647 588 break;
hudakz 9:a156d3de5647 589 }
hudakz 9:a156d3de5647 590 #endif
hudakz 9:a156d3de5647 591 sum = UipEthernet::chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], upper_layer_memlen);
hudakz 9:a156d3de5647 592 #ifdef UIPETHERNET_DEBUG_CHKSUM
hudakz 9:a156d3de5647 593 printf
hudakz 9:a156d3de5647 594 (
hudakz 9:a156d3de5647 595 "chksum uip_buf[%d-%d]: %d\r\n", UIP_IPH_LEN +
hudakz 9:a156d3de5647 596 UIP_LLH_LEN, UIP_IPH_LEN +
hudakz 9:a156d3de5647 597 UIP_LLH_LEN +
hudakz 9:a156d3de5647 598 upper_layer_memlen, htons(sum)
hudakz 9:a156d3de5647 599 );
hudakz 9:a156d3de5647 600 #endif
hudakz 9:a156d3de5647 601 if (upper_layer_memlen < upper_layer_len) {
hudakz 9:a156d3de5647 602 sum = phy.chksum
hudakz 9:a156d3de5647 603 (
hudakz 9:a156d3de5647 604 sum, UipEthernet::uipPacket, UIP_IPH_LEN +
hudakz 9:a156d3de5647 605 UIP_LLH_LEN +
hudakz 9:a156d3de5647 606 upper_layer_memlen, upper_layer_len -
hudakz 9:a156d3de5647 607 upper_layer_memlen
hudakz 9:a156d3de5647 608 );
hudakz 9:a156d3de5647 609 #ifdef UIPETHERNET_DEBUG_CHKSUM
hudakz 9:a156d3de5647 610 printf
hudakz 9:a156d3de5647 611 (
hudakz 9:a156d3de5647 612 "chksum uip_packet(%d)[%d-%d]: %d\r\n", uip_packet, UIP_IPH_LEN +
hudakz 9:a156d3de5647 613 UIP_LLH_LEN +
hudakz 9:a156d3de5647 614 upper_layer_memlen, UIP_IPH_LEN +
hudakz 9:a156d3de5647 615 UIP_LLH_LEN +
hudakz 9:a156d3de5647 616 upper_layer_len, htons(sum)
hudakz 9:a156d3de5647 617 );
hudakz 9:a156d3de5647 618 #endif
hudakz 9:a156d3de5647 619 }
hudakz 9:a156d3de5647 620 return(sum == 0) ? 0xffff : htons(sum);
hudakz 9:a156d3de5647 621 }
hudakz 9:a156d3de5647 622
hudakz 9:a156d3de5647 623 /**
hudakz 9:a156d3de5647 624 * @brief
hudakz 9:a156d3de5647 625 * @note
hudakz 9:a156d3de5647 626 * @param
hudakz 9:a156d3de5647 627 * @retval
hudakz 9:a156d3de5647 628 */
hudakz 9:a156d3de5647 629 uint16_t uip_ipchksum()
hudakz 9:a156d3de5647 630 {
hudakz 9:a156d3de5647 631 return UipEthernet::ethernet->ipchksum();
hudakz 9:a156d3de5647 632 }
hudakz 9:a156d3de5647 633
hudakz 9:a156d3de5647 634 #if UIP_UDP
hudakz 9:a156d3de5647 635
hudakz 9:a156d3de5647 636 /**
hudakz 9:a156d3de5647 637 * @brief
hudakz 9:a156d3de5647 638 * @note
hudakz 9:a156d3de5647 639 * @param
hudakz 9:a156d3de5647 640 * @retval
hudakz 9:a156d3de5647 641 */
hudakz 9:a156d3de5647 642 uint16_t uip_tcpchksum()
hudakz 9:a156d3de5647 643 {
hudakz 9:a156d3de5647 644 uint16_t sum = UipEthernet::ethernet->upper_layer_chksum(UIP_PROTO_TCP);
hudakz 9:a156d3de5647 645
hudakz 9:a156d3de5647 646 return sum;
hudakz 9:a156d3de5647 647 }
hudakz 9:a156d3de5647 648
hudakz 9:a156d3de5647 649 /**
hudakz 9:a156d3de5647 650 * @brief
hudakz 9:a156d3de5647 651 * @note
hudakz 9:a156d3de5647 652 * @param
hudakz 9:a156d3de5647 653 * @retval
hudakz 9:a156d3de5647 654 */
hudakz 9:a156d3de5647 655 uint16_t uip_udpchksum()
hudakz 9:a156d3de5647 656 {
hudakz 9:a156d3de5647 657 uint16_t sum = UipEthernet::ethernet->upper_layer_chksum(UIP_PROTO_UDP);
hudakz 9:a156d3de5647 658
hudakz 9:a156d3de5647 659 return sum;
hudakz 9:a156d3de5647 660 }
hudakz 9:a156d3de5647 661 #endif