mbed OS5

Fork of UIPEthernet by Zoltan Hudak

Committer:
hudakz
Date:
Fri Jun 30 19:51:28 2017 +0000
Revision:
8:4acb22344932
Parent:
6:10e42359e217
'UIPEthernet' renamed to 'uIPEthernet'; 'UIPEthernetClass' renamed to 'UIPEthernet'; added IPAddress::toString() to support printing; added print support for debugging; bugs preventing offline build with GCC ARM toolchain fixed.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:5350a66d5279 1 /*
hudakz 8:4acb22344932 2 UIPClient.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 4:d774541a34da 6 Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.com>
hudakz 4:d774541a34da 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 extern "C"
hudakz 0:5350a66d5279 22 {
hudakz 4:d774541a34da 23 #include "utility/uip-conf.h"
hudakz 4:d774541a34da 24 #include "utility/uip.h"
hudakz 4:d774541a34da 25 #include "utility/uip_arp.h"
hudakz 4:d774541a34da 26 #include "utility/millis.h"
hudakz 0:5350a66d5279 27 #include "string.h"
hudakz 0:5350a66d5279 28 }
hudakz 0:5350a66d5279 29 #include "UIPEthernet.h"
hudakz 0:5350a66d5279 30 #include "UIPClient.h"
hudakz 0:5350a66d5279 31 #include "Dns.h"
hudakz 0:5350a66d5279 32
hudakz 0:5350a66d5279 33 #define UIP_TCP_PHYH_LEN UIP_LLH_LEN + UIP_IPTCPH_LEN
hudakz 0:5350a66d5279 34
hudakz 8:4acb22344932 35 uip_userdata_t UIPClient::all_data[UIP_CONNS];
hudakz 0:5350a66d5279 36
hudakz 0:5350a66d5279 37 /**
hudakz 0:5350a66d5279 38 * @brief
hudakz 0:5350a66d5279 39 * @note
hudakz 0:5350a66d5279 40 * @param
hudakz 0:5350a66d5279 41 * @retval
hudakz 0:5350a66d5279 42 */
hudakz 0:5350a66d5279 43 UIPClient::UIPClient(void) :
hudakz 4:d774541a34da 44 data(NULL)
hudakz 0:5350a66d5279 45 { }
hudakz 0:5350a66d5279 46
hudakz 0:5350a66d5279 47 /**
hudakz 0:5350a66d5279 48 * @brief
hudakz 0:5350a66d5279 49 * @note
hudakz 0:5350a66d5279 50 * @param
hudakz 0:5350a66d5279 51 * @retval
hudakz 0:5350a66d5279 52 */
hudakz 4:d774541a34da 53 UIPClient::UIPClient(uip_userdata_t* conn_data) :
hudakz 4:d774541a34da 54 data(conn_data)
hudakz 0:5350a66d5279 55 { }
hudakz 0:5350a66d5279 56
hudakz 0:5350a66d5279 57 /**
hudakz 0:5350a66d5279 58 * @brief
hudakz 0:5350a66d5279 59 * @note
hudakz 0:5350a66d5279 60 * @param
hudakz 0:5350a66d5279 61 * @retval
hudakz 0:5350a66d5279 62 */
hudakz 0:5350a66d5279 63 int UIPClient::connect(IPAddress ip, uint16_t port) {
hudakz 4:d774541a34da 64 stop();
hudakz 4:d774541a34da 65
hudakz 0:5350a66d5279 66 uip_ipaddr_t ipaddr;
hudakz 0:5350a66d5279 67 uip_ip_addr(ipaddr, ip);
hudakz 4:d774541a34da 68
hudakz 4:d774541a34da 69 struct uip_conn* conn = uip_connect(&ipaddr, htons(port));
hudakz 8:4acb22344932 70 if (conn)
hudakz 4:d774541a34da 71 {
hudakz 4:d774541a34da 72 #if UIP_CONNECT_TIMEOUT > 0
hudakz 4:d774541a34da 73 int32_t timeout = millis() + 1000 * UIP_CONNECT_TIMEOUT;
hudakz 4:d774541a34da 74 #endif
hudakz 8:4acb22344932 75 while ((conn->tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) {
hudakz 8:4acb22344932 76 uIPEthernet.tick();
hudakz 8:4acb22344932 77 if ((conn->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
hudakz 4:d774541a34da 78 data = (uip_userdata_t*)conn->appstate;
hudakz 0:5350a66d5279 79 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 8:4acb22344932 80 printf("connected, state: %d, first packet in: %d\r\n", data->state, data->packets_in[0]);
hudakz 0:5350a66d5279 81 #endif
hudakz 0:5350a66d5279 82 return 1;
hudakz 0:5350a66d5279 83 }
hudakz 4:d774541a34da 84
hudakz 4:d774541a34da 85 #if UIP_CONNECT_TIMEOUT > 0
hudakz 8:4acb22344932 86 if (((int32_t) (millis() - timeout)) > 0) {
hudakz 4:d774541a34da 87 conn->tcpstateflags = UIP_CLOSED;
hudakz 4:d774541a34da 88 break;
hudakz 4:d774541a34da 89 }
hudakz 4:d774541a34da 90 #endif
hudakz 0:5350a66d5279 91 }
hudakz 0:5350a66d5279 92 }
hudakz 0:5350a66d5279 93
hudakz 0:5350a66d5279 94 return 0;
hudakz 0:5350a66d5279 95 }
hudakz 0:5350a66d5279 96
hudakz 0:5350a66d5279 97 /**
hudakz 0:5350a66d5279 98 * @brief
hudakz 0:5350a66d5279 99 * @note
hudakz 0:5350a66d5279 100 * @param
hudakz 0:5350a66d5279 101 * @retval
hudakz 0:5350a66d5279 102 */
hudakz 0:5350a66d5279 103 int UIPClient::connect(const char* host, uint16_t port) {
hudakz 0:5350a66d5279 104
hudakz 0:5350a66d5279 105 // Look up the host first
hudakz 0:5350a66d5279 106 int ret = 0;
hudakz 0:5350a66d5279 107 #if UIP_UDP
hudakz 0:5350a66d5279 108 DNSClient dns;
hudakz 0:5350a66d5279 109 IPAddress remote_addr;
hudakz 0:5350a66d5279 110
hudakz 8:4acb22344932 111 dns.begin(UIPEthernet::_dnsServerAddress);
hudakz 0:5350a66d5279 112 ret = dns.getHostByName(host, remote_addr);
hudakz 8:4acb22344932 113 if (ret == 1) {
hudakz 0:5350a66d5279 114 return connect(remote_addr, port);
hudakz 0:5350a66d5279 115 }
hudakz 0:5350a66d5279 116 #endif
hudakz 0:5350a66d5279 117 return ret;
hudakz 0:5350a66d5279 118 }
hudakz 0:5350a66d5279 119
hudakz 0:5350a66d5279 120 /**
hudakz 0:5350a66d5279 121 * @brief
hudakz 0:5350a66d5279 122 * @note
hudakz 0:5350a66d5279 123 * @param
hudakz 0:5350a66d5279 124 * @retval
hudakz 0:5350a66d5279 125 */
hudakz 0:5350a66d5279 126 void UIPClient::stop(void) {
hudakz 8:4acb22344932 127 if (data && data->state)
hudakz 4:d774541a34da 128 {
hudakz 4:d774541a34da 129 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 8:4acb22344932 130 printf("before stop(), with data\r\n");
hudakz 4:d774541a34da 131 _dumpAllData();
hudakz 4:d774541a34da 132 #endif
hudakz 0:5350a66d5279 133 _flushBlocks(&data->packets_in[0]);
hudakz 8:4acb22344932 134 if (data->state & UIP_CLIENT_REMOTECLOSED) {
hudakz 4:d774541a34da 135 data->state = 0;
hudakz 0:5350a66d5279 136 }
hudakz 0:5350a66d5279 137 else {
hudakz 0:5350a66d5279 138 data->state |= UIP_CLIENT_CLOSE;
hudakz 0:5350a66d5279 139 }
hudakz 0:5350a66d5279 140
hudakz 4:d774541a34da 141 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 8:4acb22344932 142 printf("after stop()\r\n");
hudakz 4:d774541a34da 143 _dumpAllData();
hudakz 4:d774541a34da 144 #endif
hudakz 0:5350a66d5279 145 }
hudakz 0:5350a66d5279 146
hudakz 4:d774541a34da 147 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 4:d774541a34da 148 else {
hudakz 8:4acb22344932 149 printf("stop(), data: NULL\r\n");
hudakz 4:d774541a34da 150 }
hudakz 4:d774541a34da 151 #endif
hudakz 4:d774541a34da 152 data = NULL;
hudakz 8:4acb22344932 153 uIPEthernet.tick();
hudakz 0:5350a66d5279 154 }
hudakz 0:5350a66d5279 155
hudakz 0:5350a66d5279 156 /**
hudakz 0:5350a66d5279 157 * @brief
hudakz 0:5350a66d5279 158 * @note
hudakz 0:5350a66d5279 159 * @param
hudakz 0:5350a66d5279 160 * @retval
hudakz 0:5350a66d5279 161 */
hudakz 0:5350a66d5279 162 uint8_t UIPClient::connected(void) {
hudakz 4:d774541a34da 163 return(data && (data->packets_in[0] != NOBLOCK || (data->state & UIP_CLIENT_CONNECTED))) ? 1 : 0;
hudakz 0:5350a66d5279 164 }
hudakz 0:5350a66d5279 165
hudakz 0:5350a66d5279 166 /**
hudakz 0:5350a66d5279 167 * @brief
hudakz 0:5350a66d5279 168 * @note
hudakz 0:5350a66d5279 169 * @param
hudakz 0:5350a66d5279 170 * @retval
hudakz 0:5350a66d5279 171 */
hudakz 0:5350a66d5279 172 bool UIPClient::operator==(const UIPClient& rhs) {
hudakz 4:d774541a34da 173 return data && rhs.data && (data == rhs.data);
hudakz 0:5350a66d5279 174 }
hudakz 0:5350a66d5279 175
hudakz 0:5350a66d5279 176 /**
hudakz 0:5350a66d5279 177 * @brief
hudakz 0:5350a66d5279 178 * @note
hudakz 0:5350a66d5279 179 * @param
hudakz 0:5350a66d5279 180 * @retval
hudakz 0:5350a66d5279 181 */
hudakz 0:5350a66d5279 182 UIPClient::operator bool(void) {
hudakz 8:4acb22344932 183 uIPEthernet.tick();
hudakz 4:d774541a34da 184 return data && (!(data->state & UIP_CLIENT_REMOTECLOSED) || data->packets_in[0] != NOBLOCK);
hudakz 0:5350a66d5279 185 }
hudakz 0:5350a66d5279 186
hudakz 0:5350a66d5279 187 /**
hudakz 0:5350a66d5279 188 * @brief
hudakz 0:5350a66d5279 189 * @note
hudakz 0:5350a66d5279 190 * @param
hudakz 0:5350a66d5279 191 * @retval
hudakz 0:5350a66d5279 192 */
hudakz 0:5350a66d5279 193 size_t UIPClient::write(uint8_t c) {
hudakz 4:d774541a34da 194 return _write(data, &c, 1);
hudakz 0:5350a66d5279 195 }
hudakz 0:5350a66d5279 196
hudakz 0:5350a66d5279 197 /**
hudakz 0:5350a66d5279 198 * @brief
hudakz 0:5350a66d5279 199 * @note
hudakz 0:5350a66d5279 200 * @param
hudakz 0:5350a66d5279 201 * @retval
hudakz 0:5350a66d5279 202 */
hudakz 0:5350a66d5279 203 size_t UIPClient::write(const uint8_t* buf, size_t size) {
hudakz 4:d774541a34da 204 return _write(data, buf, size);
hudakz 0:5350a66d5279 205 }
hudakz 0:5350a66d5279 206
hudakz 0:5350a66d5279 207 /**
hudakz 0:5350a66d5279 208 * @brief
hudakz 0:5350a66d5279 209 * @note
hudakz 0:5350a66d5279 210 * @param
hudakz 0:5350a66d5279 211 * @retval
hudakz 0:5350a66d5279 212 */
hudakz 4:d774541a34da 213 size_t UIPClient::_write(uip_userdata_t* u, const uint8_t* buf, size_t size) {
hudakz 4:d774541a34da 214 int remain = size;
hudakz 4:d774541a34da 215 uint16_t written;
hudakz 0:5350a66d5279 216 #if UIP_ATTEMPTS_ON_WRITE > 0
hudakz 4:d774541a34da 217 uint16_t attempts = UIP_ATTEMPTS_ON_WRITE;
hudakz 0:5350a66d5279 218 #endif
hudakz 8:4acb22344932 219 repeat : uIPEthernet.tick();
hudakz 8:4acb22344932 220 if (u && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))) {
hudakz 4:d774541a34da 221 uint8_t p = _currentBlock(&u->packets_out[0]);
hudakz 8:4acb22344932 222 if (u->packets_out[p] == NOBLOCK)
hudakz 0:5350a66d5279 223 {
hudakz 0:5350a66d5279 224 newpacket:
hudakz 8:4acb22344932 225 u->packets_out[p] = uIPEthernet.network.allocBlock(UIP_SOCKET_DATALEN);
hudakz 8:4acb22344932 226 if (u->packets_out[p] == NOBLOCK)
hudakz 0:5350a66d5279 227 {
hudakz 0:5350a66d5279 228 #if UIP_ATTEMPTS_ON_WRITE > 0
hudakz 8:4acb22344932 229 if ((--attempts) > 0)
hudakz 0:5350a66d5279 230 #endif
hudakz 0:5350a66d5279 231 #if UIP_ATTEMPTS_ON_WRITE != 0
hudakz 0:5350a66d5279 232 goto repeat;
hudakz 0:5350a66d5279 233 #endif
hudakz 0:5350a66d5279 234 goto ready;
hudakz 0:5350a66d5279 235 }
hudakz 0:5350a66d5279 236
hudakz 0:5350a66d5279 237 u->out_pos = 0;
hudakz 0:5350a66d5279 238 }
hudakz 0:5350a66d5279 239
hudakz 0:5350a66d5279 240 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 8:4acb22344932 241 printf("UIPClient.write: writePacket(%d) pos: %d, buf[%d-%d]\r\n", u->packets_out[p], u->out_pos, size - remain, remain);
hudakz 0:5350a66d5279 242 #endif
hudakz 8:4acb22344932 243 written = uIPEthernet.network.writePacket
hudakz 4:d774541a34da 244 (
hudakz 4:d774541a34da 245 u->packets_out[p],
hudakz 4:d774541a34da 246 u->out_pos,
hudakz 4:d774541a34da 247 (uint8_t*)buf + size - remain,
hudakz 4:d774541a34da 248 remain
hudakz 4:d774541a34da 249 );
hudakz 0:5350a66d5279 250 remain -= written;
hudakz 0:5350a66d5279 251 u->out_pos += written;
hudakz 8:4acb22344932 252 if (remain > 0) {
hudakz 8:4acb22344932 253 if (p == UIP_SOCKET_NUMPACKETS - 1)
hudakz 0:5350a66d5279 254 {
hudakz 0:5350a66d5279 255 #if UIP_ATTEMPTS_ON_WRITE > 0
hudakz 8:4acb22344932 256 if ((--attempts) > 0)
hudakz 0:5350a66d5279 257 #endif
hudakz 0:5350a66d5279 258 #if UIP_ATTEMPTS_ON_WRITE != 0
hudakz 0:5350a66d5279 259 goto repeat;
hudakz 0:5350a66d5279 260 #endif
hudakz 0:5350a66d5279 261 goto ready;
hudakz 0:5350a66d5279 262 }
hudakz 0:5350a66d5279 263
hudakz 0:5350a66d5279 264 p++;
hudakz 0:5350a66d5279 265 goto newpacket;
hudakz 0:5350a66d5279 266 }
hudakz 0:5350a66d5279 267
hudakz 0:5350a66d5279 268 ready:
hudakz 4:d774541a34da 269 #if UIP_CLIENT_TIMER >= 0
hudakz 4:d774541a34da 270 u->timer = millis() + UIP_CLIENT_TIMER;
hudakz 4:d774541a34da 271 #endif
hudakz 0:5350a66d5279 272 return size - remain;
hudakz 0:5350a66d5279 273 }
hudakz 0:5350a66d5279 274
hudakz 0:5350a66d5279 275 return -1;
hudakz 0:5350a66d5279 276 }
hudakz 0:5350a66d5279 277
hudakz 0:5350a66d5279 278 /**
hudakz 0:5350a66d5279 279 * @brief
hudakz 0:5350a66d5279 280 * @note
hudakz 0:5350a66d5279 281 * @param
hudakz 0:5350a66d5279 282 * @retval
hudakz 0:5350a66d5279 283 */
hudakz 0:5350a66d5279 284 int UIPClient::available(void) {
hudakz 8:4acb22344932 285 if (*this)
hudakz 0:5350a66d5279 286 return _available(data);
hudakz 4:d774541a34da 287 return 0;
hudakz 0:5350a66d5279 288 }
hudakz 0:5350a66d5279 289
hudakz 0:5350a66d5279 290 /**
hudakz 0:5350a66d5279 291 * @brief
hudakz 0:5350a66d5279 292 * @note
hudakz 0:5350a66d5279 293 * @param
hudakz 0:5350a66d5279 294 * @retval
hudakz 0:5350a66d5279 295 */
hudakz 0:5350a66d5279 296 int UIPClient::_available(uip_userdata_t* u) {
hudakz 0:5350a66d5279 297 int len = 0;
hudakz 8:4acb22344932 298 for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) {
hudakz 8:4acb22344932 299 len += uIPEthernet.network.blockSize(u->packets_in[i]);
hudakz 0:5350a66d5279 300 }
hudakz 0:5350a66d5279 301
hudakz 0:5350a66d5279 302 return len;
hudakz 0:5350a66d5279 303 }
hudakz 0:5350a66d5279 304
hudakz 0:5350a66d5279 305 /**
hudakz 0:5350a66d5279 306 * @brief
hudakz 0:5350a66d5279 307 * @note
hudakz 0:5350a66d5279 308 * @param
hudakz 0:5350a66d5279 309 * @retval
hudakz 0:5350a66d5279 310 */
hudakz 0:5350a66d5279 311 int UIPClient::read(uint8_t* buf, size_t size) {
hudakz 8:4acb22344932 312 if (*this) {
hudakz 4:d774541a34da 313 uint16_t remain = size;
hudakz 8:4acb22344932 314 if (data->packets_in[0] == NOBLOCK)
hudakz 0:5350a66d5279 315 return 0;
hudakz 0:5350a66d5279 316
hudakz 4:d774541a34da 317 uint16_t read;
hudakz 8:4acb22344932 318 do {
hudakz 8:4acb22344932 319 read = uIPEthernet.network.readPacket(data->packets_in[0], 0, buf + size - remain, remain);
hudakz 8:4acb22344932 320 if (read == uIPEthernet.network.blockSize(data->packets_in[0])) {
hudakz 0:5350a66d5279 321 remain -= read;
hudakz 4:d774541a34da 322 _eatBlock(&data->packets_in[0]);
hudakz 4:d774541a34da 323 if
hudakz 4:d774541a34da 324 (
hudakz 4:d774541a34da 325 uip_stopped(&uip_conns[data->state & UIP_CLIENT_SOCKETS])
hudakz 4:d774541a34da 326 && !(data->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))
hudakz 4:d774541a34da 327 ) data->state |= UIP_CLIENT_RESTART;
hudakz 8:4acb22344932 328 if (data->packets_in[0] == NOBLOCK) {
hudakz 8:4acb22344932 329 if (data->state & UIP_CLIENT_REMOTECLOSED) {
hudakz 4:d774541a34da 330 data->state = 0;
hudakz 4:d774541a34da 331 data = NULL;
hudakz 4:d774541a34da 332 }
hudakz 4:d774541a34da 333
hudakz 0:5350a66d5279 334 return size - remain;
hudakz 4:d774541a34da 335 }
hudakz 0:5350a66d5279 336 }
hudakz 0:5350a66d5279 337 else {
hudakz 8:4acb22344932 338 uIPEthernet.network.resizeBlock(data->packets_in[0], read);
hudakz 0:5350a66d5279 339 break;
hudakz 0:5350a66d5279 340 }
hudakz 8:4acb22344932 341 } while (remain > 0);
hudakz 0:5350a66d5279 342 return size;
hudakz 0:5350a66d5279 343 }
hudakz 0:5350a66d5279 344
hudakz 0:5350a66d5279 345 return -1;
hudakz 0:5350a66d5279 346 }
hudakz 0:5350a66d5279 347
hudakz 0:5350a66d5279 348 /**
hudakz 0:5350a66d5279 349 * @brief
hudakz 0:5350a66d5279 350 * @note
hudakz 0:5350a66d5279 351 * @param
hudakz 0:5350a66d5279 352 * @retval
hudakz 0:5350a66d5279 353 */
hudakz 0:5350a66d5279 354 int UIPClient::read(void) {
hudakz 8:4acb22344932 355 static uint8_t c;
hudakz 8:4acb22344932 356 if (read(&c, 1) < 0)
hudakz 0:5350a66d5279 357 return -1;
hudakz 0:5350a66d5279 358 return c;
hudakz 0:5350a66d5279 359 }
hudakz 0:5350a66d5279 360
hudakz 0:5350a66d5279 361 /**
hudakz 0:5350a66d5279 362 * @brief
hudakz 0:5350a66d5279 363 * @note
hudakz 0:5350a66d5279 364 * @param
hudakz 0:5350a66d5279 365 * @retval
hudakz 0:5350a66d5279 366 */
hudakz 0:5350a66d5279 367 int UIPClient::peek(void) {
hudakz 8:4acb22344932 368 static uint8_t c;
hudakz 8:4acb22344932 369 if (*this) {
hudakz 8:4acb22344932 370 if (data->packets_in[0] != NOBLOCK) {
hudakz 8:4acb22344932 371 uIPEthernet.network.readPacket(data->packets_in[0], 0, &c, 1);
hudakz 0:5350a66d5279 372 return c;
hudakz 0:5350a66d5279 373 }
hudakz 0:5350a66d5279 374 }
hudakz 0:5350a66d5279 375
hudakz 0:5350a66d5279 376 return -1;
hudakz 0:5350a66d5279 377 }
hudakz 0:5350a66d5279 378
hudakz 0:5350a66d5279 379 /**
hudakz 0:5350a66d5279 380 * @brief
hudakz 0:5350a66d5279 381 * @note
hudakz 0:5350a66d5279 382 * @param
hudakz 0:5350a66d5279 383 * @retval
hudakz 0:5350a66d5279 384 */
hudakz 0:5350a66d5279 385 void UIPClient::flush(void) {
hudakz 8:4acb22344932 386 if (*this) {
hudakz 0:5350a66d5279 387 _flushBlocks(&data->packets_in[0]);
hudakz 0:5350a66d5279 388 }
hudakz 0:5350a66d5279 389 }
hudakz 0:5350a66d5279 390
hudakz 0:5350a66d5279 391 /**
hudakz 0:5350a66d5279 392 * @brief
hudakz 0:5350a66d5279 393 * @note
hudakz 0:5350a66d5279 394 * @param
hudakz 0:5350a66d5279 395 * @retval
hudakz 0:5350a66d5279 396 */
hudakz 4:d774541a34da 397 void uipclient_appcall(void) {
hudakz 4:d774541a34da 398 uint16_t send_len = 0;
hudakz 4:d774541a34da 399 uip_userdata_t* u = (uip_userdata_t*)uip_conn->appstate;
hudakz 8:4acb22344932 400 if (!u && uip_connected())
hudakz 0:5350a66d5279 401 {
hudakz 0:5350a66d5279 402 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 8:4acb22344932 403 printf("UIPClient uip_connected\r\n");
hudakz 4:d774541a34da 404 UIPClient::_dumpAllData();
hudakz 0:5350a66d5279 405 #endif
hudakz 4:d774541a34da 406 u = (uip_userdata_t*)UIPClient::_allocateData();
hudakz 8:4acb22344932 407 if (u) {
hudakz 4:d774541a34da 408 uip_conn->appstate = u;
hudakz 4:d774541a34da 409 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 8:4acb22344932 410 printf("UIPClient allocated state: %d", u->state);
hudakz 4:d774541a34da 411 #endif
hudakz 4:d774541a34da 412 }
hudakz 0:5350a66d5279 413
hudakz 4:d774541a34da 414 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 4:d774541a34da 415 else
hudakz 8:4acb22344932 416 printf("UIPClient allocation failed\r\n");
hudakz 4:d774541a34da 417 #endif
hudakz 0:5350a66d5279 418 }
hudakz 0:5350a66d5279 419
hudakz 8:4acb22344932 420 if (u) {
hudakz 8:4acb22344932 421 if (uip_newdata())
hudakz 0:5350a66d5279 422 {
hudakz 0:5350a66d5279 423 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 8:4acb22344932 424 printf("UIPClient uip_newdata, uip_len: %d\r\n", uip_len);
hudakz 0:5350a66d5279 425 #endif
hudakz 8:4acb22344932 426 if (uip_len && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))) {
hudakz 8:4acb22344932 427 for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) {
hudakz 8:4acb22344932 428 if (u->packets_in[i] == NOBLOCK) {
hudakz 8:4acb22344932 429 u->packets_in[i] = uIPEthernet.network.allocBlock(uip_len);
hudakz 8:4acb22344932 430 if (u->packets_in[i] != NOBLOCK) {
hudakz 8:4acb22344932 431 uIPEthernet.network.copyPacket
hudakz 4:d774541a34da 432 (
hudakz 4:d774541a34da 433 u->packets_in[i],
hudakz 4:d774541a34da 434 0,
hudakz 8:4acb22344932 435 UIPEthernet::in_packet,
hudakz 4:d774541a34da 436 ((uint8_t*)uip_appdata) - uip_buf,
hudakz 4:d774541a34da 437 uip_len
hudakz 4:d774541a34da 438 );
hudakz 8:4acb22344932 439 if (i == UIP_SOCKET_NUMPACKETS - 1)
hudakz 4:d774541a34da 440 uip_stop();
hudakz 4:d774541a34da 441 goto finish_newdata;
hudakz 0:5350a66d5279 442 }
hudakz 0:5350a66d5279 443 }
hudakz 0:5350a66d5279 444 }
hudakz 0:5350a66d5279 445
hudakz 8:4acb22344932 446 UIPEthernet::packetstate &= ~UIPETHERNET_FREEPACKET;
hudakz 0:5350a66d5279 447 uip_stop();
hudakz 0:5350a66d5279 448 }
hudakz 0:5350a66d5279 449 }
hudakz 0:5350a66d5279 450
hudakz 0:5350a66d5279 451 finish_newdata:
hudakz 8:4acb22344932 452 if (u->state & UIP_CLIENT_RESTART) {
hudakz 0:5350a66d5279 453 u->state &= ~UIP_CLIENT_RESTART;
hudakz 0:5350a66d5279 454 uip_restart();
hudakz 0:5350a66d5279 455 }
hudakz 0:5350a66d5279 456
hudakz 0:5350a66d5279 457 // If the connection has been closed, save received but unread data.
hudakz 8:4acb22344932 458 if (uip_closed() || uip_timedout())
hudakz 0:5350a66d5279 459 {
hudakz 0:5350a66d5279 460 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 8:4acb22344932 461 printf("UIPClient uip_closed\r\n");
hudakz 4:d774541a34da 462 UIPClient::_dumpAllData();
hudakz 0:5350a66d5279 463 #endif
hudakz 0:5350a66d5279 464 // drop outgoing packets not sent yet:
hudakz 0:5350a66d5279 465
hudakz 4:d774541a34da 466 UIPClient::_flushBlocks(&u->packets_out[0]);
hudakz 8:4acb22344932 467 if (u->packets_in[0] != NOBLOCK) {
hudakz 4:d774541a34da 468 ((uip_userdata_closed_t*)u)->lport = uip_conn->lport;
hudakz 4:d774541a34da 469 u->state |= UIP_CLIENT_REMOTECLOSED;
hudakz 0:5350a66d5279 470 }
hudakz 4:d774541a34da 471 else
hudakz 4:d774541a34da 472 u->state = 0;
hudakz 0:5350a66d5279 473
hudakz 0:5350a66d5279 474 // disassociate appdata.
hudakz 4:d774541a34da 475 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 8:4acb22344932 476 printf("after UIPClient uip_closed\r\n");
hudakz 4:d774541a34da 477 UIPClient::_dumpAllData();
hudakz 4:d774541a34da 478 #endif
hudakz 4:d774541a34da 479 uip_conn->appstate = NULL;
hudakz 4:d774541a34da 480 goto finish;
hudakz 0:5350a66d5279 481 }
hudakz 0:5350a66d5279 482
hudakz 8:4acb22344932 483 if (uip_acked())
hudakz 0:5350a66d5279 484 {
hudakz 0:5350a66d5279 485 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 8:4acb22344932 486 printf("UIPClient uip_acked\r\n");
hudakz 0:5350a66d5279 487 #endif
hudakz 4:d774541a34da 488 UIPClient::_eatBlock(&u->packets_out[0]);
hudakz 0:5350a66d5279 489 }
hudakz 0:5350a66d5279 490
hudakz 8:4acb22344932 491 if (uip_poll() || uip_rexmit())
hudakz 0:5350a66d5279 492 {
hudakz 0:5350a66d5279 493 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 8:4acb22344932 494 //printf("UIPClient uip_poll\r\n");
hudakz 0:5350a66d5279 495 #endif
hudakz 8:4acb22344932 496 if (u->packets_out[0] != NOBLOCK) {
hudakz 8:4acb22344932 497 if (u->packets_out[1] == NOBLOCK) {
hudakz 4:d774541a34da 498 send_len = u->out_pos;
hudakz 8:4acb22344932 499 if (send_len > 0) {
hudakz 8:4acb22344932 500 uIPEthernet.network.resizeBlock(u->packets_out[0], 0, send_len);
hudakz 0:5350a66d5279 501 }
hudakz 0:5350a66d5279 502 }
hudakz 0:5350a66d5279 503 else
hudakz 8:4acb22344932 504 send_len = uIPEthernet.network.blockSize(u->packets_out[0]);
hudakz 8:4acb22344932 505 if (send_len > 0) {
hudakz 8:4acb22344932 506 UIPEthernet::uip_hdrlen = ((uint8_t*)uip_appdata) - uip_buf;
hudakz 8:4acb22344932 507 UIPEthernet::uip_packet = uIPEthernet.network.allocBlock(UIPEthernet::uip_hdrlen + send_len);
hudakz 8:4acb22344932 508 if (UIPEthernet::uip_packet != NOBLOCK) {
hudakz 8:4acb22344932 509 uIPEthernet.network.copyPacket
hudakz 4:d774541a34da 510 (
hudakz 8:4acb22344932 511 UIPEthernet::uip_packet,
hudakz 8:4acb22344932 512 UIPEthernet::uip_hdrlen,
hudakz 4:d774541a34da 513 u->packets_out[0],
hudakz 4:d774541a34da 514 0,
hudakz 4:d774541a34da 515 send_len
hudakz 4:d774541a34da 516 );
hudakz 8:4acb22344932 517 UIPEthernet::packetstate |= UIPETHERNET_SENDPACKET;
hudakz 0:5350a66d5279 518 }
hudakz 4:d774541a34da 519 }
hudakz 0:5350a66d5279 520
hudakz 4:d774541a34da 521 goto finish;
hudakz 0:5350a66d5279 522 }
hudakz 0:5350a66d5279 523 }
hudakz 0:5350a66d5279 524
hudakz 0:5350a66d5279 525 // don't close connection unless all outgoing packets are sent
hudakz 8:4acb22344932 526 if (u->state & UIP_CLIENT_CLOSE)
hudakz 0:5350a66d5279 527 {
hudakz 0:5350a66d5279 528 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 8:4acb22344932 529 printf("UIPClient state UIP_CLIENT_CLOSE\r\n");
hudakz 4:d774541a34da 530 UIPClient::_dumpAllData();
hudakz 0:5350a66d5279 531 #endif
hudakz 8:4acb22344932 532 if (u->packets_out[0] == NOBLOCK) {
hudakz 4:d774541a34da 533 u->state = 0;
hudakz 4:d774541a34da 534 uip_conn->appstate = NULL;
hudakz 0:5350a66d5279 535 uip_close();
hudakz 4:d774541a34da 536 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 8:4acb22344932 537 printf("no blocks out -> free userdata\r\n");
hudakz 4:d774541a34da 538 UIPClient::_dumpAllData();
hudakz 4:d774541a34da 539 #endif
hudakz 0:5350a66d5279 540 }
hudakz 4:d774541a34da 541 else {
hudakz 0:5350a66d5279 542 uip_stop();
hudakz 4:d774541a34da 543 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 8:4acb22344932 544 printf("blocks outstanding transfer -> uip_stop()\r\n");
hudakz 4:d774541a34da 545 #endif
hudakz 4:d774541a34da 546 }
hudakz 0:5350a66d5279 547 }
hudakz 0:5350a66d5279 548 }
hudakz 0:5350a66d5279 549
hudakz 4:d774541a34da 550 finish:
hudakz 4:d774541a34da 551 uip_send(uip_appdata, send_len);
hudakz 4:d774541a34da 552 uip_len = send_len;
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 4:d774541a34da 561 uip_userdata_t* UIPClient::_allocateData(void) {
hudakz 8:4acb22344932 562 for (uint8_t sock = 0; sock < UIP_CONNS; sock++) {
hudakz 4:d774541a34da 563 uip_userdata_t* data = &UIPClient::all_data[sock];
hudakz 8:4acb22344932 564 if (!data->state) {
hudakz 4:d774541a34da 565 data->state = sock | UIP_CLIENT_CONNECTED;
hudakz 4:d774541a34da 566 memset(&data->packets_in[0], 0, sizeof(uip_userdata_t) - sizeof(data->state));
hudakz 4:d774541a34da 567 return data;
hudakz 4:d774541a34da 568 }
hudakz 4:d774541a34da 569 }
hudakz 4:d774541a34da 570
hudakz 4:d774541a34da 571 return NULL;
hudakz 4:d774541a34da 572 }
hudakz 4:d774541a34da 573
hudakz 4:d774541a34da 574 /**
hudakz 4:d774541a34da 575 * @brief
hudakz 4:d774541a34da 576 * @note
hudakz 4:d774541a34da 577 * @param
hudakz 4:d774541a34da 578 * @retval
hudakz 4:d774541a34da 579 */
hudakz 4:d774541a34da 580 uint8_t UIPClient::_currentBlock(memhandle* block) {
hudakz 8:4acb22344932 581 for (uint8_t i = 1; i < UIP_SOCKET_NUMPACKETS; i++) {
hudakz 8:4acb22344932 582 if (block[i] == NOBLOCK)
hudakz 4:d774541a34da 583 return i - 1;
hudakz 4:d774541a34da 584 }
hudakz 4:d774541a34da 585
hudakz 4:d774541a34da 586 return UIP_SOCKET_NUMPACKETS - 1;
hudakz 0:5350a66d5279 587 }
hudakz 0:5350a66d5279 588
hudakz 0:5350a66d5279 589 /**
hudakz 0:5350a66d5279 590 * @brief
hudakz 0:5350a66d5279 591 * @note
hudakz 0:5350a66d5279 592 * @param
hudakz 0:5350a66d5279 593 * @retval
hudakz 0:5350a66d5279 594 */
hudakz 0:5350a66d5279 595 void UIPClient::_eatBlock(memhandle* block)
hudakz 0:5350a66d5279 596 {
hudakz 0:5350a66d5279 597 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 0:5350a66d5279 598 memhandle* start = block;
hudakz 8:4acb22344932 599 printf("eatblock(%d): ", *block);
hudakz 8:4acb22344932 600 for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) {
hudakz 8:4acb22344932 601 printf("%d ", start[i]);
hudakz 0:5350a66d5279 602 }
hudakz 0:5350a66d5279 603
hudakz 8:4acb22344932 604 printf("-> ");
hudakz 0:5350a66d5279 605 #endif
hudakz 8:4acb22344932 606 uIPEthernet.network.freeBlock(block[0]);
hudakz 8:4acb22344932 607 for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS - 1; i++) {
hudakz 4:d774541a34da 608 block[i] = block[i + 1];
hudakz 4:d774541a34da 609 }
hudakz 0:5350a66d5279 610
hudakz 4:d774541a34da 611 block[UIP_SOCKET_NUMPACKETS - 1] = NOBLOCK;
hudakz 0:5350a66d5279 612 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 8:4acb22344932 613 for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) {
hudakz 8:4acb22344932 614 printf("%d ", start[i]);
hudakz 0:5350a66d5279 615 }
hudakz 0:5350a66d5279 616
hudakz 8:4acb22344932 617 printf("\r\n");
hudakz 0:5350a66d5279 618 #endif
hudakz 0:5350a66d5279 619 }
hudakz 0:5350a66d5279 620
hudakz 0:5350a66d5279 621 /**
hudakz 0:5350a66d5279 622 * @brief
hudakz 0:5350a66d5279 623 * @note
hudakz 0:5350a66d5279 624 * @param
hudakz 0:5350a66d5279 625 * @retval
hudakz 0:5350a66d5279 626 */
hudakz 0:5350a66d5279 627 void UIPClient::_flushBlocks(memhandle* block) {
hudakz 8:4acb22344932 628 for (uint8_t i = 0; i < UIP_SOCKET_NUMPACKETS; i++) {
hudakz 8:4acb22344932 629 uIPEthernet.network.freeBlock(block[i]);
hudakz 4:d774541a34da 630 block[i] = NOBLOCK;
hudakz 0:5350a66d5279 631 }
hudakz 0:5350a66d5279 632 }
hudakz 2:049ce85163c5 633
hudakz 4:d774541a34da 634 #ifdef UIPETHERNET_DEBUG_CLIENT
hudakz 4:d774541a34da 635
hudakz 4:d774541a34da 636 /**
hudakz 4:d774541a34da 637 * @brief
hudakz 4:d774541a34da 638 * @note
hudakz 4:d774541a34da 639 * @param
hudakz 4:d774541a34da 640 * @retval
hudakz 4:d774541a34da 641 */
hudakz 4:d774541a34da 642 void UIPClient::_dumpAllData(void) {
hudakz 8:4acb22344932 643 for (uint8_t i = 0; i < UIP_CONNS; i++) {
hudakz 8:4acb22344932 644 printf("UIPClient::all_data[%d], state:%d packets_in: ", i, all_data[i].state);
hudakz 8:4acb22344932 645 for (uint8_t j = 0; j < UIP_SOCKET_NUMPACKETS; j++) {
hudakz 8:4acb22344932 646 printf("%d ", all_data[i].packets_in[j]);
hudakz 4:d774541a34da 647 }
hudakz 4:d774541a34da 648
hudakz 8:4acb22344932 649 printf("\r\n");
hudakz 8:4acb22344932 650 if (all_data[i].state & UIP_CLIENT_REMOTECLOSED) {
hudakz 8:4acb22344932 651 printf("state remote closed, local port: %d", htons(((uip_userdata_closed_t *) (&all_data[i]))->lport));
hudakz 8:4acb22344932 652 printf("\r\n");
hudakz 4:d774541a34da 653 }
hudakz 4:d774541a34da 654 else {
hudakz 8:4acb22344932 655 printf("packets_out: ");
hudakz 8:4acb22344932 656 for (uint8_t j = 0; j < UIP_SOCKET_NUMPACKETS; j++) {
hudakz 8:4acb22344932 657 printf("%d ", all_data[i].packets_out[j]);
hudakz 4:d774541a34da 658 }
hudakz 4:d774541a34da 659
hudakz 8:4acb22344932 660 printf("\r\n");
hudakz 8:4acb22344932 661 printf("out_pos: %d\r\n", all_data[i].out_pos);
hudakz 4:d774541a34da 662 }
hudakz 4:d774541a34da 663 }
hudakz 4:d774541a34da 664 }
hudakz 4:d774541a34da 665 #endif
hudakz 8:4acb22344932 666