UIPEthernet library for Arduino IDE, Eclipse with arduino plugin and MBED/SMeshStudio (AVR,STM32F,ESP8266,Intel ARC32,Nordic nRF51,Teensy boards,Realtek Ameba(RTL8195A,RTL8710)), ENC28j60 network chip. Compatible with Wiznet W5100 Ethernet library API. Compiled and tested on Nucleo-F302R8. Master repository is: https://github.com/UIPEthernet/UIPEthernet/

Committer:
cassyarduino
Date:
Tue Jan 23 15:08:43 2018 +0100
Revision:
39:deeb00b81cc9
Parent:
9:312e0937630f
Release: 2.0.4

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cassyarduino 0:e3fb1267e3c3 1 /*
cassyarduino 0:e3fb1267e3c3 2 UIPUdp.cpp - Arduino implementation of a uIP wrapper class.
cassyarduino 0:e3fb1267e3c3 3 Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
cassyarduino 0:e3fb1267e3c3 4 All rights reserved.
cassyarduino 0:e3fb1267e3c3 5
cassyarduino 0:e3fb1267e3c3 6 This program is free software: you can redistribute it and/or modify
cassyarduino 0:e3fb1267e3c3 7 it under the terms of the GNU General Public License as published by
cassyarduino 0:e3fb1267e3c3 8 the Free Software Foundation, either version 3 of the License, or
cassyarduino 0:e3fb1267e3c3 9 (at your option) any later version.
cassyarduino 0:e3fb1267e3c3 10
cassyarduino 0:e3fb1267e3c3 11 This program is distributed in the hope that it will be useful,
cassyarduino 0:e3fb1267e3c3 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
cassyarduino 0:e3fb1267e3c3 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
cassyarduino 0:e3fb1267e3c3 14 GNU General Public License for more details.
cassyarduino 0:e3fb1267e3c3 15
cassyarduino 0:e3fb1267e3c3 16 You should have received a copy of the GNU General Public License
cassyarduino 0:e3fb1267e3c3 17 along with this program. If not, see <http://www.gnu.org/licenses/>.
cassyarduino 0:e3fb1267e3c3 18 */
cassyarduino 0:e3fb1267e3c3 19
cassyarduino 0:e3fb1267e3c3 20 #include "UIPEthernet.h"
cassyarduino 0:e3fb1267e3c3 21 #include "UIPUdp.h"
cassyarduino 0:e3fb1267e3c3 22 #include "Dns.h"
cassyarduino 0:e3fb1267e3c3 23 #include "utility/logging.h"
cassyarduino 0:e3fb1267e3c3 24
cassyarduino 0:e3fb1267e3c3 25 extern "C" {
cassyarduino 39:deeb00b81cc9 26 #include "utility/uipopt.h"
cassyarduino 0:e3fb1267e3c3 27 #include "utility/uip.h"
cassyarduino 0:e3fb1267e3c3 28 #include "utility/uip_arp.h"
cassyarduino 0:e3fb1267e3c3 29 }
cassyarduino 0:e3fb1267e3c3 30
cassyarduino 0:e3fb1267e3c3 31 #if UIP_UDP
cassyarduino 0:e3fb1267e3c3 32 #define UIP_ARPHDRSIZE 42
cassyarduino 0:e3fb1267e3c3 33 #define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
cassyarduino 0:e3fb1267e3c3 34
cassyarduino 0:e3fb1267e3c3 35 // Constructor
cassyarduino 0:e3fb1267e3c3 36 UIPUDP::UIPUDP(void) :
cassyarduino 0:e3fb1267e3c3 37 _uip_udp_conn(NULL)
cassyarduino 0:e3fb1267e3c3 38 {
cassyarduino 0:e3fb1267e3c3 39 memset(&appdata,0,sizeof(appdata));
cassyarduino 0:e3fb1267e3c3 40 }
cassyarduino 0:e3fb1267e3c3 41
cassyarduino 0:e3fb1267e3c3 42 // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
cassyarduino 0:e3fb1267e3c3 43 uint8_t
cassyarduino 0:e3fb1267e3c3 44 UIPUDP::begin(uint16_t port)
cassyarduino 0:e3fb1267e3c3 45 {
cassyarduino 0:e3fb1267e3c3 46 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 47 LogObject.uart_send_strln(F("UIPUDP::begin(uint16_t port) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 48 #endif
cassyarduino 0:e3fb1267e3c3 49 if (!_uip_udp_conn)
cassyarduino 0:e3fb1267e3c3 50 {
cassyarduino 0:e3fb1267e3c3 51 _uip_udp_conn = uip_udp_new(NULL, 0);
cassyarduino 0:e3fb1267e3c3 52 }
cassyarduino 0:e3fb1267e3c3 53 if (_uip_udp_conn)
cassyarduino 0:e3fb1267e3c3 54 {
cassyarduino 0:e3fb1267e3c3 55 uip_udp_bind(_uip_udp_conn,htons(port));
cassyarduino 0:e3fb1267e3c3 56 _uip_udp_conn->appstate = &appdata;
cassyarduino 0:e3fb1267e3c3 57 return 1;
cassyarduino 0:e3fb1267e3c3 58 }
cassyarduino 0:e3fb1267e3c3 59 return 0;
cassyarduino 0:e3fb1267e3c3 60 }
cassyarduino 0:e3fb1267e3c3 61
cassyarduino 0:e3fb1267e3c3 62 // Finish with the UDP socket
cassyarduino 0:e3fb1267e3c3 63 void
cassyarduino 0:e3fb1267e3c3 64 UIPUDP::stop(void)
cassyarduino 0:e3fb1267e3c3 65 {
cassyarduino 0:e3fb1267e3c3 66 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 67 LogObject.uart_send_strln(F("UIPUDP::stop(void) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 68 #endif
cassyarduino 0:e3fb1267e3c3 69 if (_uip_udp_conn)
cassyarduino 0:e3fb1267e3c3 70 {
cassyarduino 0:e3fb1267e3c3 71 uip_udp_remove(_uip_udp_conn);
cassyarduino 0:e3fb1267e3c3 72 _uip_udp_conn->appstate = NULL;
cassyarduino 0:e3fb1267e3c3 73 _uip_udp_conn=NULL;
cassyarduino 0:e3fb1267e3c3 74 Enc28J60Network::freeBlock(appdata.packet_in);
cassyarduino 0:e3fb1267e3c3 75 Enc28J60Network::freeBlock(appdata.packet_next);
cassyarduino 0:e3fb1267e3c3 76 Enc28J60Network::freeBlock(appdata.packet_out);
cassyarduino 0:e3fb1267e3c3 77 memset(&appdata,0,sizeof(appdata));
cassyarduino 0:e3fb1267e3c3 78 }
cassyarduino 0:e3fb1267e3c3 79 }
cassyarduino 0:e3fb1267e3c3 80
cassyarduino 0:e3fb1267e3c3 81 // Sending UDP packets
cassyarduino 0:e3fb1267e3c3 82
cassyarduino 0:e3fb1267e3c3 83 // Start building up a packet to send to the remote host specific in ip and port
cassyarduino 0:e3fb1267e3c3 84 // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
cassyarduino 0:e3fb1267e3c3 85 int
cassyarduino 0:e3fb1267e3c3 86 UIPUDP::beginPacket(IPAddress ip, uint16_t port)
cassyarduino 0:e3fb1267e3c3 87 {
cassyarduino 0:e3fb1267e3c3 88 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 89 LogObject.uart_send_strln(F("UIPUDP::beginPacket(IPAddress ip, uint16_t port) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 90 #endif
cassyarduino 0:e3fb1267e3c3 91 UIPEthernetClass::tick();
cassyarduino 0:e3fb1267e3c3 92 if (ip && port)
cassyarduino 0:e3fb1267e3c3 93 {
cassyarduino 0:e3fb1267e3c3 94 uip_ipaddr_t ripaddr;
cassyarduino 0:e3fb1267e3c3 95 uip_ip_addr(&ripaddr, ip);
cassyarduino 0:e3fb1267e3c3 96 #if ACTLOGLEVEL>=LOG_DEBUG
cassyarduino 0:e3fb1267e3c3 97 LogObject.uart_send_str(F("UIPUDP::beginPacket DEBUG:udp beginPacket, "));
cassyarduino 0:e3fb1267e3c3 98 #endif
cassyarduino 0:e3fb1267e3c3 99 if (_uip_udp_conn)
cassyarduino 0:e3fb1267e3c3 100 {
cassyarduino 0:e3fb1267e3c3 101 _uip_udp_conn->rport = htons(port);
cassyarduino 0:e3fb1267e3c3 102 uip_ipaddr_copy(_uip_udp_conn->ripaddr, &ripaddr);
cassyarduino 0:e3fb1267e3c3 103 }
cassyarduino 0:e3fb1267e3c3 104 else
cassyarduino 0:e3fb1267e3c3 105 {
cassyarduino 0:e3fb1267e3c3 106 _uip_udp_conn = uip_udp_new(&ripaddr,htons(port));
cassyarduino 0:e3fb1267e3c3 107 if (_uip_udp_conn)
cassyarduino 0:e3fb1267e3c3 108 {
cassyarduino 0:e3fb1267e3c3 109 #if ACTLOGLEVEL>=LOG_DEBUG
cassyarduino 0:e3fb1267e3c3 110 LogObject.uart_send_str(F("new connection, "));
cassyarduino 0:e3fb1267e3c3 111 #endif
cassyarduino 0:e3fb1267e3c3 112 _uip_udp_conn->appstate = &appdata;
cassyarduino 0:e3fb1267e3c3 113 }
cassyarduino 0:e3fb1267e3c3 114 else
cassyarduino 0:e3fb1267e3c3 115 {
cassyarduino 0:e3fb1267e3c3 116 #if ACTLOGLEVEL>=LOG_ERR
cassyarduino 0:e3fb1267e3c3 117 LogObject.uart_send_strln(F("\nUIPUDP::beginPacket ERROR:failed to allocate new connection"));
cassyarduino 0:e3fb1267e3c3 118 #endif
cassyarduino 0:e3fb1267e3c3 119 return 0;
cassyarduino 0:e3fb1267e3c3 120 }
cassyarduino 0:e3fb1267e3c3 121 }
cassyarduino 0:e3fb1267e3c3 122 #if ACTLOGLEVEL>=LOG_DEBUG
cassyarduino 0:e3fb1267e3c3 123 LogObject.uart_send_str(F("rip: "));
cassyarduino 9:312e0937630f 124 #if defined(ARDUINO)
cassyarduino 9:312e0937630f 125 LogObject.print(ip);
cassyarduino 9:312e0937630f 126 #endif
cassyarduino 9:312e0937630f 127 #if defined(__MBED__)
cassyarduino 9:312e0937630f 128 LogObject.printf("%d.%d.%d.%d",ip[0],ip[1],ip[2],ip[3]);
cassyarduino 9:312e0937630f 129 #endif
cassyarduino 0:e3fb1267e3c3 130 LogObject.uart_send_str(F(", port: "));
cassyarduino 0:e3fb1267e3c3 131 LogObject.uart_send_decln(port);
cassyarduino 0:e3fb1267e3c3 132 #endif
cassyarduino 0:e3fb1267e3c3 133 }
cassyarduino 0:e3fb1267e3c3 134 if (_uip_udp_conn)
cassyarduino 0:e3fb1267e3c3 135 {
cassyarduino 0:e3fb1267e3c3 136 if (appdata.packet_out == NOBLOCK)
cassyarduino 0:e3fb1267e3c3 137 {
cassyarduino 0:e3fb1267e3c3 138 appdata.packet_out = Enc28J60Network::allocBlock(UIP_UDP_MAXPACKETSIZE);
cassyarduino 0:e3fb1267e3c3 139 appdata.out_pos = UIP_UDP_PHYH_LEN;
cassyarduino 0:e3fb1267e3c3 140 if (appdata.packet_out != NOBLOCK)
cassyarduino 0:e3fb1267e3c3 141 return 1;
cassyarduino 0:e3fb1267e3c3 142 #if ACTLOGLEVEL>=LOG_ERR
cassyarduino 0:e3fb1267e3c3 143 else
cassyarduino 0:e3fb1267e3c3 144 LogObject.uart_send_strln(F("\nUIPUDP::beginPacket ERROR:Failed to allocate memory for packet"));
cassyarduino 0:e3fb1267e3c3 145 #endif
cassyarduino 0:e3fb1267e3c3 146 }
cassyarduino 0:e3fb1267e3c3 147 #if ACTLOGLEVEL>=LOG_WARNING
cassyarduino 0:e3fb1267e3c3 148 else
cassyarduino 0:e3fb1267e3c3 149 LogObject.uart_send_strln(F("\nUIPUDP::beginPacket WARNING:Previous packet on that connection not sent yet"));
cassyarduino 0:e3fb1267e3c3 150 #endif
cassyarduino 0:e3fb1267e3c3 151 }
cassyarduino 0:e3fb1267e3c3 152 return 0;
cassyarduino 0:e3fb1267e3c3 153 }
cassyarduino 0:e3fb1267e3c3 154
cassyarduino 0:e3fb1267e3c3 155 // Start building up a packet to send to the remote host specific in host and port
cassyarduino 0:e3fb1267e3c3 156 // Returns 1 if successful, 0 if there was a problem resolving the hostname or port
cassyarduino 0:e3fb1267e3c3 157 int
cassyarduino 0:e3fb1267e3c3 158 UIPUDP::beginPacket(const char *host, uint16_t port)
cassyarduino 0:e3fb1267e3c3 159 {
cassyarduino 0:e3fb1267e3c3 160 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 161 LogObject.uart_send_strln(F("UIPUDP::beginPacket(const char *host, uint16_t port) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 162 #endif
cassyarduino 0:e3fb1267e3c3 163 // Look up the host first
cassyarduino 0:e3fb1267e3c3 164 int ret = 0;
cassyarduino 0:e3fb1267e3c3 165 DNSClient dns;
cassyarduino 0:e3fb1267e3c3 166 IPAddress remote_addr;
cassyarduino 0:e3fb1267e3c3 167
cassyarduino 0:e3fb1267e3c3 168 dns.begin(UIPEthernet.dnsServerIP());
cassyarduino 0:e3fb1267e3c3 169 ret = dns.getHostByName(host, remote_addr);
cassyarduino 0:e3fb1267e3c3 170 if (ret == 1) {
cassyarduino 0:e3fb1267e3c3 171 return beginPacket(remote_addr, port);
cassyarduino 0:e3fb1267e3c3 172 } else {
cassyarduino 0:e3fb1267e3c3 173 return ret;
cassyarduino 0:e3fb1267e3c3 174 }
cassyarduino 0:e3fb1267e3c3 175 }
cassyarduino 0:e3fb1267e3c3 176
cassyarduino 0:e3fb1267e3c3 177 // Finish off this packet and send it
cassyarduino 0:e3fb1267e3c3 178 // Returns 1 if the packet was sent successfully, 0 if there was an error
cassyarduino 0:e3fb1267e3c3 179 int
cassyarduino 0:e3fb1267e3c3 180 UIPUDP::endPacket(void)
cassyarduino 0:e3fb1267e3c3 181 {
cassyarduino 0:e3fb1267e3c3 182 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 183 LogObject.uart_send_strln(F("UIPUDP::endPacket(void) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 184 #endif
cassyarduino 0:e3fb1267e3c3 185 if (_uip_udp_conn && appdata.packet_out != NOBLOCK)
cassyarduino 0:e3fb1267e3c3 186 {
cassyarduino 0:e3fb1267e3c3 187 appdata.send = true;
cassyarduino 0:e3fb1267e3c3 188 Enc28J60Network::resizeBlock(appdata.packet_out,0,appdata.out_pos);
cassyarduino 0:e3fb1267e3c3 189 uip_udp_periodic_conn(_uip_udp_conn);
cassyarduino 0:e3fb1267e3c3 190 if (uip_len > 0)
cassyarduino 0:e3fb1267e3c3 191 {
cassyarduino 0:e3fb1267e3c3 192 _send(&appdata);
cassyarduino 0:e3fb1267e3c3 193 return 1;
cassyarduino 0:e3fb1267e3c3 194 }
cassyarduino 0:e3fb1267e3c3 195 }
cassyarduino 0:e3fb1267e3c3 196 return 0;
cassyarduino 0:e3fb1267e3c3 197 }
cassyarduino 0:e3fb1267e3c3 198
cassyarduino 0:e3fb1267e3c3 199 // Write a single byte into the packet
cassyarduino 0:e3fb1267e3c3 200 size_t
cassyarduino 0:e3fb1267e3c3 201 UIPUDP::write(uint8_t c)
cassyarduino 0:e3fb1267e3c3 202 {
cassyarduino 0:e3fb1267e3c3 203 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 204 LogObject.uart_send_strln(F("UIPUDP::write(uint8_t c) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 205 #endif
cassyarduino 0:e3fb1267e3c3 206 return write(&c,1);
cassyarduino 0:e3fb1267e3c3 207 }
cassyarduino 0:e3fb1267e3c3 208
cassyarduino 0:e3fb1267e3c3 209 // Write size bytes from buffer into the packet
cassyarduino 0:e3fb1267e3c3 210 size_t
cassyarduino 0:e3fb1267e3c3 211 UIPUDP::write(const uint8_t *buffer, size_t size)
cassyarduino 0:e3fb1267e3c3 212 {
cassyarduino 0:e3fb1267e3c3 213 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 214 LogObject.uart_send_strln(F("UIPUDP::write(const uint8_t *buffer, size_t size) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 215 #endif
cassyarduino 0:e3fb1267e3c3 216 if (appdata.packet_out != NOBLOCK)
cassyarduino 0:e3fb1267e3c3 217 {
cassyarduino 0:e3fb1267e3c3 218 size_t ret = Enc28J60Network::writePacket(appdata.packet_out,appdata.out_pos,(uint8_t*)buffer,size);
cassyarduino 0:e3fb1267e3c3 219 appdata.out_pos += ret;
cassyarduino 0:e3fb1267e3c3 220 return ret;
cassyarduino 0:e3fb1267e3c3 221 }
cassyarduino 0:e3fb1267e3c3 222 return 0;
cassyarduino 0:e3fb1267e3c3 223 }
cassyarduino 0:e3fb1267e3c3 224
cassyarduino 0:e3fb1267e3c3 225 // Start processing the next available incoming packet
cassyarduino 0:e3fb1267e3c3 226 // Returns the size of the packet in bytes, or 0 if no packets are available
cassyarduino 0:e3fb1267e3c3 227 int
cassyarduino 0:e3fb1267e3c3 228 UIPUDP::parsePacket(void)
cassyarduino 0:e3fb1267e3c3 229 {
cassyarduino 0:e3fb1267e3c3 230 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 231 LogObject.uart_send_strln(F("UIPUDP::parsePacket(void) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 232 #endif
cassyarduino 0:e3fb1267e3c3 233 UIPEthernetClass::tick();
cassyarduino 0:e3fb1267e3c3 234 if (appdata.packet_in != NOBLOCK)
cassyarduino 0:e3fb1267e3c3 235 {
cassyarduino 0:e3fb1267e3c3 236 #if ACTLOGLEVEL>=LOG_DEBUG
cassyarduino 0:e3fb1267e3c3 237 LogObject.uart_send_str(F("UIPUDP::parsePacket(void) DEBUG:udp parsePacket freeing previous packet: "));
cassyarduino 0:e3fb1267e3c3 238 LogObject.uart_send_decln(appdata.packet_in);
cassyarduino 0:e3fb1267e3c3 239 #endif
cassyarduino 0:e3fb1267e3c3 240 Enc28J60Network::freeBlock(appdata.packet_in);
cassyarduino 0:e3fb1267e3c3 241 }
cassyarduino 0:e3fb1267e3c3 242
cassyarduino 0:e3fb1267e3c3 243 appdata.packet_in = appdata.packet_next;
cassyarduino 0:e3fb1267e3c3 244 appdata.packet_next = NOBLOCK;
cassyarduino 0:e3fb1267e3c3 245
cassyarduino 0:e3fb1267e3c3 246 #if ACTLOGLEVEL>=LOG_DEBUG
cassyarduino 0:e3fb1267e3c3 247 if (appdata.packet_in != NOBLOCK)
cassyarduino 0:e3fb1267e3c3 248 {
cassyarduino 0:e3fb1267e3c3 249 LogObject.uart_send_str(F("UIPUDP::parsePacket(void) DEBUG:udp parsePacket received packet: "));
cassyarduino 0:e3fb1267e3c3 250 LogObject.uart_send_dec(appdata.packet_in);
cassyarduino 0:e3fb1267e3c3 251 }
cassyarduino 0:e3fb1267e3c3 252 #endif
cassyarduino 0:e3fb1267e3c3 253 int size = Enc28J60Network::blockSize(appdata.packet_in);
cassyarduino 0:e3fb1267e3c3 254 #if ACTLOGLEVEL>=LOG_DEBUG
cassyarduino 0:e3fb1267e3c3 255 if (appdata.packet_in != NOBLOCK)
cassyarduino 0:e3fb1267e3c3 256 {
cassyarduino 0:e3fb1267e3c3 257 LogObject.uart_send_str(F(", size: "));
cassyarduino 0:e3fb1267e3c3 258 LogObject.uart_send_decln(size);
cassyarduino 0:e3fb1267e3c3 259 }
cassyarduino 0:e3fb1267e3c3 260 #endif
cassyarduino 0:e3fb1267e3c3 261 return size;
cassyarduino 0:e3fb1267e3c3 262 }
cassyarduino 0:e3fb1267e3c3 263
cassyarduino 0:e3fb1267e3c3 264 // Number of bytes remaining in the current packet
cassyarduino 0:e3fb1267e3c3 265 int
cassyarduino 0:e3fb1267e3c3 266 UIPUDP::available(void)
cassyarduino 0:e3fb1267e3c3 267 {
cassyarduino 0:e3fb1267e3c3 268 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 269 LogObject.uart_send_strln(F("UIPUDP::available(void) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 270 #endif
cassyarduino 0:e3fb1267e3c3 271 UIPEthernetClass::tick();
cassyarduino 0:e3fb1267e3c3 272 return Enc28J60Network::blockSize(appdata.packet_in);
cassyarduino 0:e3fb1267e3c3 273 }
cassyarduino 0:e3fb1267e3c3 274
cassyarduino 0:e3fb1267e3c3 275 // Read a single byte from the current packet
cassyarduino 0:e3fb1267e3c3 276 int
cassyarduino 0:e3fb1267e3c3 277 UIPUDP::read(void)
cassyarduino 0:e3fb1267e3c3 278 {
cassyarduino 0:e3fb1267e3c3 279 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 280 LogObject.uart_send_strln(F("UIPUDP::read(void) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 281 #endif
cassyarduino 0:e3fb1267e3c3 282 unsigned char c;
cassyarduino 0:e3fb1267e3c3 283 if (read(&c,1) > 0)
cassyarduino 0:e3fb1267e3c3 284 {
cassyarduino 0:e3fb1267e3c3 285 return c;
cassyarduino 0:e3fb1267e3c3 286 }
cassyarduino 0:e3fb1267e3c3 287 return -1;
cassyarduino 0:e3fb1267e3c3 288 }
cassyarduino 0:e3fb1267e3c3 289
cassyarduino 0:e3fb1267e3c3 290 // Read up to len bytes from the current packet and place them into buffer
cassyarduino 0:e3fb1267e3c3 291 // Returns the number of bytes read, or 0 if none are available
cassyarduino 0:e3fb1267e3c3 292 int
cassyarduino 0:e3fb1267e3c3 293 UIPUDP::read(unsigned char* buffer, size_t len)
cassyarduino 0:e3fb1267e3c3 294 {
cassyarduino 0:e3fb1267e3c3 295 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 296 LogObject.uart_send_strln(F("UIPUDP::read(unsigned char* buffer, size_t len) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 297 #endif
cassyarduino 0:e3fb1267e3c3 298 UIPEthernetClass::tick();
cassyarduino 0:e3fb1267e3c3 299 if (appdata.packet_in != NOBLOCK)
cassyarduino 0:e3fb1267e3c3 300 {
cassyarduino 0:e3fb1267e3c3 301 memaddress read = Enc28J60Network::readPacket(appdata.packet_in,0,(uint8_t*)buffer,(uint16_t)len);
cassyarduino 0:e3fb1267e3c3 302 if (read == Enc28J60Network::blockSize(appdata.packet_in))
cassyarduino 0:e3fb1267e3c3 303 {
cassyarduino 0:e3fb1267e3c3 304 Enc28J60Network::freeBlock(appdata.packet_in);
cassyarduino 0:e3fb1267e3c3 305 appdata.packet_in = NOBLOCK;
cassyarduino 0:e3fb1267e3c3 306 }
cassyarduino 0:e3fb1267e3c3 307 else
cassyarduino 0:e3fb1267e3c3 308 Enc28J60Network::resizeBlock(appdata.packet_in,read);
cassyarduino 0:e3fb1267e3c3 309 return read;
cassyarduino 0:e3fb1267e3c3 310 }
cassyarduino 0:e3fb1267e3c3 311 return 0;
cassyarduino 0:e3fb1267e3c3 312 }
cassyarduino 0:e3fb1267e3c3 313
cassyarduino 0:e3fb1267e3c3 314 // Return the next byte from the current packet without moving on to the next byte
cassyarduino 0:e3fb1267e3c3 315 int
cassyarduino 0:e3fb1267e3c3 316 UIPUDP::peek(void)
cassyarduino 0:e3fb1267e3c3 317 {
cassyarduino 0:e3fb1267e3c3 318 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 319 LogObject.uart_send_strln(F("UIPUDP::peek(void) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 320 #endif
cassyarduino 0:e3fb1267e3c3 321 UIPEthernetClass::tick();
cassyarduino 0:e3fb1267e3c3 322 if (appdata.packet_in != NOBLOCK)
cassyarduino 0:e3fb1267e3c3 323 {
cassyarduino 0:e3fb1267e3c3 324 unsigned char c;
cassyarduino 0:e3fb1267e3c3 325 if (Enc28J60Network::readPacket(appdata.packet_in,0,(uint8_t*)&c,1) == 1)
cassyarduino 0:e3fb1267e3c3 326 return c;
cassyarduino 0:e3fb1267e3c3 327 }
cassyarduino 0:e3fb1267e3c3 328 return -1;
cassyarduino 0:e3fb1267e3c3 329 }
cassyarduino 0:e3fb1267e3c3 330
cassyarduino 0:e3fb1267e3c3 331 // Finish reading the current packet
cassyarduino 0:e3fb1267e3c3 332 void
cassyarduino 0:e3fb1267e3c3 333 UIPUDP::flush(void)
cassyarduino 0:e3fb1267e3c3 334 {
cassyarduino 0:e3fb1267e3c3 335 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 336 LogObject.uart_send_strln(F("UIPUDP::flush(void) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 337 #endif
cassyarduino 0:e3fb1267e3c3 338 UIPEthernetClass::tick();
cassyarduino 0:e3fb1267e3c3 339 Enc28J60Network::freeBlock(appdata.packet_in);
cassyarduino 0:e3fb1267e3c3 340 appdata.packet_in = NOBLOCK;
cassyarduino 0:e3fb1267e3c3 341 }
cassyarduino 0:e3fb1267e3c3 342
cassyarduino 0:e3fb1267e3c3 343 // Return the IP address of the host who sent the current incoming packet
cassyarduino 0:e3fb1267e3c3 344 IPAddress
cassyarduino 0:e3fb1267e3c3 345 UIPUDP::remoteIP(void)
cassyarduino 0:e3fb1267e3c3 346 {
cassyarduino 0:e3fb1267e3c3 347 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 348 LogObject.uart_send_strln(F("UIPUDP::remoteIP(void) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 349 #endif
cassyarduino 0:e3fb1267e3c3 350 return _uip_udp_conn ? ip_addr_uip(_uip_udp_conn->ripaddr) : IPAddress();
cassyarduino 0:e3fb1267e3c3 351 }
cassyarduino 0:e3fb1267e3c3 352
cassyarduino 0:e3fb1267e3c3 353 // Return the port of the host who sent the current incoming packet
cassyarduino 0:e3fb1267e3c3 354 uint16_t
cassyarduino 0:e3fb1267e3c3 355 UIPUDP::remotePort(void)
cassyarduino 0:e3fb1267e3c3 356 {
cassyarduino 0:e3fb1267e3c3 357 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 358 LogObject.uart_send_strln(F("UIPUDP::remotePort(void) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 359 #endif
cassyarduino 0:e3fb1267e3c3 360 return _uip_udp_conn ? ntohs(_uip_udp_conn->rport) : 0;
cassyarduino 0:e3fb1267e3c3 361 }
cassyarduino 0:e3fb1267e3c3 362
cassyarduino 0:e3fb1267e3c3 363 // uIP callback function
cassyarduino 0:e3fb1267e3c3 364
cassyarduino 0:e3fb1267e3c3 365 void
cassyarduino 0:e3fb1267e3c3 366 uipudp_appcall(void) {
cassyarduino 0:e3fb1267e3c3 367 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 368 LogObject.uart_send_strln(F("uipudp_appcall(void) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 369 #endif
cassyarduino 0:e3fb1267e3c3 370 if (uip_udp_userdata_t *data = (uip_udp_userdata_t *)(uip_udp_conn->appstate))
cassyarduino 0:e3fb1267e3c3 371 {
cassyarduino 0:e3fb1267e3c3 372 if (uip_newdata())
cassyarduino 0:e3fb1267e3c3 373 {
cassyarduino 0:e3fb1267e3c3 374 if (data->packet_next == NOBLOCK)
cassyarduino 0:e3fb1267e3c3 375 {
cassyarduino 0:e3fb1267e3c3 376 uip_udp_conn->rport = UDPBUF->srcport;
cassyarduino 0:e3fb1267e3c3 377 uip_ipaddr_copy(uip_udp_conn->ripaddr,UDPBUF->srcipaddr);
cassyarduino 0:e3fb1267e3c3 378 data->packet_next = Enc28J60Network::allocBlock(ntohs(UDPBUF->udplen)-UIP_UDPH_LEN);
cassyarduino 0:e3fb1267e3c3 379 //if we are unable to allocate memory the packet is dropped. udp doesn't guarantee packet delivery
cassyarduino 0:e3fb1267e3c3 380 if (data->packet_next != NOBLOCK)
cassyarduino 0:e3fb1267e3c3 381 {
cassyarduino 0:e3fb1267e3c3 382 //discard Linklevel and IP and udp-header and any trailing bytes:
cassyarduino 0:e3fb1267e3c3 383 Enc28J60Network::copyPacket(data->packet_next,0,UIPEthernetClass::in_packet,UIP_UDP_PHYH_LEN,Enc28J60Network::blockSize(data->packet_next));
cassyarduino 0:e3fb1267e3c3 384 #if ACTLOGLEVEL>=LOG_DEBUG
cassyarduino 0:e3fb1267e3c3 385 LogObject.uart_send_str(F("uipudp_appcall(void) DEBUG:udp, uip_newdata received packet: "));
cassyarduino 0:e3fb1267e3c3 386 LogObject.uart_send_dec(data->packet_next);
cassyarduino 0:e3fb1267e3c3 387 LogObject.uart_send_str(F(", size: "));
cassyarduino 0:e3fb1267e3c3 388 LogObject.uart_send_decln(Enc28J60Network::blockSize(data->packet_next));
cassyarduino 0:e3fb1267e3c3 389 #endif
cassyarduino 0:e3fb1267e3c3 390 }
cassyarduino 0:e3fb1267e3c3 391 }
cassyarduino 0:e3fb1267e3c3 392 }
cassyarduino 0:e3fb1267e3c3 393 if (uip_poll() && data->send)
cassyarduino 0:e3fb1267e3c3 394 {
cassyarduino 0:e3fb1267e3c3 395 //set uip_slen (uip private) by calling uip_udp_send
cassyarduino 0:e3fb1267e3c3 396 #if ACTLOGLEVEL>=LOG_DEBUG
cassyarduino 0:e3fb1267e3c3 397 LogObject.uart_send_str(F("uipudp_appcall(void) DEBUG:udp, uip_poll preparing packet to send: "));
cassyarduino 0:e3fb1267e3c3 398 LogObject.uart_send_dec(data->packet_out);
cassyarduino 0:e3fb1267e3c3 399 LogObject.uart_send_str(F(", size: "));
cassyarduino 0:e3fb1267e3c3 400 LogObject.uart_send_decln(Enc28J60Network::blockSize(data->packet_out));
cassyarduino 0:e3fb1267e3c3 401 #endif
cassyarduino 0:e3fb1267e3c3 402 UIPEthernetClass::uip_packet = data->packet_out;
cassyarduino 0:e3fb1267e3c3 403 UIPEthernetClass::uip_hdrlen = UIP_UDP_PHYH_LEN;
cassyarduino 0:e3fb1267e3c3 404 uip_udp_send(data->out_pos - (UIP_UDP_PHYH_LEN));
cassyarduino 0:e3fb1267e3c3 405 }
cassyarduino 0:e3fb1267e3c3 406 }
cassyarduino 0:e3fb1267e3c3 407 }
cassyarduino 0:e3fb1267e3c3 408
cassyarduino 0:e3fb1267e3c3 409 void
cassyarduino 0:e3fb1267e3c3 410 UIPUDP::_send(uip_udp_userdata_t *data) {
cassyarduino 0:e3fb1267e3c3 411 #if ACTLOGLEVEL>=LOG_DEBUG_V3
cassyarduino 0:e3fb1267e3c3 412 LogObject.uart_send_strln(F("UIPUDP::_send(uip_udp_userdata_t *data) DEBUG_V3:Function started"));
cassyarduino 0:e3fb1267e3c3 413 #endif
cassyarduino 0:e3fb1267e3c3 414 uip_arp_out(); //add arp
cassyarduino 0:e3fb1267e3c3 415 if (uip_len == UIP_ARPHDRSIZE)
cassyarduino 0:e3fb1267e3c3 416 {
cassyarduino 0:e3fb1267e3c3 417 UIPEthernetClass::uip_packet = NOBLOCK;
cassyarduino 0:e3fb1267e3c3 418 UIPEthernetClass::packetstate &= ~UIPETHERNET_SENDPACKET;
cassyarduino 0:e3fb1267e3c3 419 #if ACTLOGLEVEL>=LOG_DEBUG
cassyarduino 0:e3fb1267e3c3 420 LogObject.uart_send_strln(F("UIPUDP::_send() DEBUG:udp, uip_poll results in ARP-packet"));
cassyarduino 0:e3fb1267e3c3 421 #endif
cassyarduino 0:e3fb1267e3c3 422 }
cassyarduino 0:e3fb1267e3c3 423 else
cassyarduino 0:e3fb1267e3c3 424 //arp found ethaddr for ip (otherwise packet is replaced by arp-request)
cassyarduino 0:e3fb1267e3c3 425 {
cassyarduino 0:e3fb1267e3c3 426 data->send = false;
cassyarduino 0:e3fb1267e3c3 427 data->packet_out = NOBLOCK;
cassyarduino 0:e3fb1267e3c3 428 UIPEthernetClass::packetstate |= UIPETHERNET_SENDPACKET;
cassyarduino 0:e3fb1267e3c3 429 #if ACTLOGLEVEL>=LOG_DEBUG
cassyarduino 0:e3fb1267e3c3 430 LogObject.uart_send_str(F("UIPUDP::_send() DEBUG:udp, uip_packet to send: "));
cassyarduino 0:e3fb1267e3c3 431 LogObject.uart_send_decln(UIPEthernetClass::uip_packet);
cassyarduino 0:e3fb1267e3c3 432 #endif
cassyarduino 0:e3fb1267e3c3 433 }
cassyarduino 0:e3fb1267e3c3 434 UIPEthernetClass::network_send();
cassyarduino 0:e3fb1267e3c3 435 }
cassyarduino 0:e3fb1267e3c3 436 #endif