Fork for fixes

Committer:
hudakz
Date:
Tue Aug 27 22:08:54 2019 +0000
Revision:
10:e4ddab81e6a8
Parent:
9:a156d3de5647
Child:
11:647d53d146f1
Added methods for TcpClient to get remote client's IP address and peer name.

Who changed what in which revision?

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