Fork for fixes

Committer:
ivo_n
Date:
Sat Sep 26 08:31:41 2020 +0000
Revision:
22:a0b1d0e6d237
Parent:
19:58e840279555
Everything seems to work

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