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