mbed OS5

Fork of UIPEthernet by Zoltan Hudak

Committer:
hudakz
Date:
Sat Dec 20 11:08:11 2014 +0000
Revision:
2:049ce85163c5
Parent:
0:5350a66d5279
Child:
4:d774541a34da
02 Name clash with "Ethernet" fixed for LPC1768

Who changed what in which revision?

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