mbed OS5

Fork of UIPEthernet by Zoltan Hudak

Committer:
hudakz
Date:
Sun Mar 08 20:26:56 2015 +0000
Revision:
4:d774541a34da
Parent:
2:049ce85163c5
Child:
8:4acb22344932
Version 1.09 (fixed leaking client-data caused by race-condition on remote close)

Who changed what in which revision?

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