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:
Sat Aug 31 20:34:52 2019 +0000
Revision:
13:95c00132cd98
Parent:
11:647d53d146f1
Child:
14:7648334eb41b
TcpClient, TcpServer and UipEthernet modified to make TcpClient work.

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