mbed OS5

Fork of UIPEthernet by Zoltan Hudak

Committer:
pilotak
Date:
Sun Aug 06 16:01:26 2017 +0000
Revision:
9:e55652bed36c
Parent:
8:4acb22344932
mBed OS5

Who changed what in which revision?

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