1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-21 10:26:06 +03:00

Replace chain of UDP pbufs with a single pbuf before sending (#1009)

Packets up to 1492 bytes may be sent this way.
Also reduced pbuf_unit_size to 128 bytes.
This commit is contained in:
Ivan Grokhotkov 2015-12-06 20:22:54 +03:00
parent c4436d8d04
commit 3d1fbc60ab

View File

@ -1,9 +1,9 @@
/* /*
UdpContext.h - UDP connection handling on top of lwIP UdpContext.h - UDP connection handling on top of lwIP
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment. This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -206,10 +206,10 @@ public:
size_t max_size = _rx_buf->len - _rx_buf_offset; size_t max_size = _rx_buf->len - _rx_buf_offset;
size = (size < max_size) ? size : max_size; size = (size < max_size) ? size : max_size;
DEBUGV(":urd %d, %d, %d\r\n", size, _rx_buf->len, _rx_buf_offset); DEBUGV(":urd %d, %d, %d\r\n", size, _rx_buf->len, _rx_buf_offset);
os_memcpy(dst, reinterpret_cast<char*>(_rx_buf->payload) + _rx_buf_offset, size); memcpy(dst, reinterpret_cast<char*>(_rx_buf->payload) + _rx_buf_offset, size);
_consume(size); _consume(size);
return size; return size;
} }
@ -236,7 +236,7 @@ public:
{ {
_reserve(_tx_buf_offset + size); _reserve(_tx_buf_offset + size);
} }
size_t left_to_copy = size; size_t left_to_copy = size;
while(left_to_copy) while(left_to_copy)
{ {
@ -249,7 +249,7 @@ public:
continue; continue;
} }
size_t will_copy = (left_to_copy < free_cur) ? left_to_copy : free_cur; size_t will_copy = (left_to_copy < free_cur) ? left_to_copy : free_cur;
os_memcpy(reinterpret_cast<char*>(_tx_buf_cur->payload) + used_cur, data, will_copy); memcpy(reinterpret_cast<char*>(_tx_buf_cur->payload) + used_cur, data, will_copy);
_tx_buf_offset += will_copy; _tx_buf_offset += will_copy;
left_to_copy -= will_copy; left_to_copy -= will_copy;
data += will_copy; data += will_copy;
@ -259,18 +259,20 @@ public:
void send(ip_addr_t* addr = 0, uint16_t port = 0) void send(ip_addr_t* addr = 0, uint16_t port = 0)
{ {
size_t orig_size = _tx_buf_head->tot_len;
size_t data_size = _tx_buf_offset; size_t data_size = _tx_buf_offset;
size_t size_adjustment = orig_size - data_size; pbuf* tx_copy = pbuf_alloc(PBUF_TRANSPORT, data_size, PBUF_RAM);
for (pbuf* p = _tx_buf_head; p; p = p->next) uint8_t* dst = reinterpret_cast<uint8_t*>(tx_copy->payload);
{ for (pbuf* p = _tx_buf_head; p; p = p->next) {
p->tot_len -= size_adjustment; size_t will_copy = (data_size < p->len) ? data_size : p->len;
if (!p->next) memcpy(dst, p->payload, will_copy);
{ dst += will_copy;
p->len = p->tot_len; data_size -= will_copy;
}
} }
pbuf_free(_tx_buf_head);
_tx_buf_head = 0;
_tx_buf_cur = 0;
_tx_buf_offset = 0;
if (!addr) { if (!addr) {
addr = &_dest_addr; addr = &_dest_addr;
@ -282,30 +284,16 @@ public:
_pcb->ttl = _multicast_ttl; _pcb->ttl = _multicast_ttl;
} }
udp_sendto(_pcb, _tx_buf_head, addr, port); udp_sendto(_pcb, tx_copy, addr, port);
_pcb->ttl = old_ttl; _pcb->ttl = old_ttl;
pbuf_free(tx_copy);
for (pbuf* p = _tx_buf_head; p; p = p->next)
{
p->tot_len += size_adjustment;
if (!p->next)
{
p->len = p->tot_len;
}
}
pbuf_free(_tx_buf_head);
_tx_buf_head = 0;
_tx_buf_cur = 0;
_tx_buf_offset = 0;
} }
private: private:
void _reserve(size_t size) void _reserve(size_t size)
{ {
const size_t pbuf_unit_size = 512; const size_t pbuf_unit_size = 128;
if (!_tx_buf_head) if (!_tx_buf_head)
{ {
_tx_buf_head = pbuf_alloc(PBUF_TRANSPORT, pbuf_unit_size, PBUF_RAM); _tx_buf_head = pbuf_alloc(PBUF_TRANSPORT, pbuf_unit_size, PBUF_RAM);
@ -357,7 +345,7 @@ private:
} }
static void _s_recv(void *arg, static void _s_recv(void *arg,
udp_pcb *upcb, pbuf *p, udp_pcb *upcb, pbuf *p,
ip_addr_t *addr, u16_t port) ip_addr_t *addr, u16_t port)
{ {