mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-04 14:29:39 +00:00
Further update to ARP queueing: Changed pbuf_copy() implementation so that it can be reused (don't allocate the target pbuf inside pbuf_copy()).
This commit is contained in:
parent
be316e81a7
commit
79d9b36ece
@ -129,6 +129,11 @@ HISTORY
|
||||
|
||||
++ Bug fixes:
|
||||
|
||||
2007-05-04 Simon Goldschmidt
|
||||
* pbuf.c, pbuf.h, etharp.c: Further update to ARP queueing: Changed pbuf_copy()
|
||||
implementation so that it can be reused (don't allocate the target
|
||||
pbuf inside pbuf_copy()).
|
||||
|
||||
2007-05-04 Simon Goldschmidt
|
||||
* memp.c: checked in patch #5913: in memp_malloc() we can return memp as mem
|
||||
to save a little RAM (next pointer of memp is not used while not in pool).
|
||||
|
@ -775,39 +775,73 @@ pbuf_dechain(struct pbuf *p)
|
||||
*
|
||||
* @return Pointer to head of pbuf chain
|
||||
*/
|
||||
struct pbuf *
|
||||
pbuf_copy(struct pbuf *p)
|
||||
err_t
|
||||
pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
|
||||
{
|
||||
u16_t copied=0;
|
||||
struct pbuf *p_copy;
|
||||
LWIP_ASSERT("pbuf_copy: p != NULL\n", p != NULL);
|
||||
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 3, ("pbuf_copy(%p)\n", (void*)p));
|
||||
u16_t offset_to=0, offset_from=0, len;
|
||||
#ifdef LWIP_DEBUG
|
||||
u16_t copied=0, shouldbe;
|
||||
#endif
|
||||
|
||||
/* allocate one pbuf to hold the complete packet */
|
||||
p_copy = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
|
||||
if(p_copy == NULL) {
|
||||
/* out of memory */
|
||||
return NULL;
|
||||
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 3, ("pbuf_copy(%p, %p)\n", p_to, p_from));
|
||||
|
||||
/* is the target big enough to hold the source? */
|
||||
if ((p_to == NULL) || (p_from == NULL) || (p_to->tot_len < p_from->tot_len)) {
|
||||
LWIP_ASSERT("pbuf_copy: p_to != NULL\n", p_to != NULL);
|
||||
LWIP_ASSERT("pbuf_copy: p_from != NULL\n", p_from != NULL);
|
||||
LWIP_ASSERT("pbuf_copy: p_to->tot_len >= p_from->tot_len\n", p_to->tot_len >= p_from->tot_len);
|
||||
return ERR_ARG;
|
||||
}
|
||||
#ifdef LWIP_DEBUG
|
||||
shouldbe = p_from->tot_len;
|
||||
#endif
|
||||
|
||||
/* iterate through pbuf chain */
|
||||
do
|
||||
{
|
||||
LWIP_ASSERT("p_to != NULL", p_to != NULL);
|
||||
/* copy one part of the original chain */
|
||||
memcpy((char*)p_copy->payload + copied, p->payload, p->len);
|
||||
copied += p->len;
|
||||
LWIP_DEBUGF(PBUF_DEBUG, ("pbuf_copy: copied pbuf %p\n", (void *)p));
|
||||
if ((p_to->len - offset_to) >= (p_from->len - offset_from)) {
|
||||
/* complete current p_from fits into current p_to */
|
||||
len = p_from->len - offset_from;
|
||||
} else {
|
||||
/* current p_from does not fit into current p_to */
|
||||
len = p_to->len - offset_to;
|
||||
}
|
||||
memcpy((u8_t*)p_to->payload + offset_to, (u8_t*)p_from->payload + offset_from, len);
|
||||
#ifdef LWIP_DEBUG
|
||||
copied += len;
|
||||
#endif
|
||||
offset_to += len;
|
||||
offset_from += len;
|
||||
LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len);
|
||||
if (offset_to == p_to->len) {
|
||||
/* on to next p_to (if any) */
|
||||
offset_to = 0;
|
||||
p_to = p_to->next;
|
||||
}
|
||||
LWIP_ASSERT("offset_from <= p_from->len", offset_to <= p_from->len);
|
||||
if (offset_from >= p_from->len) {
|
||||
/* on to next p_from (if any) */
|
||||
offset_from = 0;
|
||||
p_from = p_from->next;
|
||||
}
|
||||
|
||||
if(p->len == p->tot_len) {
|
||||
if((p_from != NULL) && (p_from->len == p_from->tot_len)) {
|
||||
/* don't copy more than one packet! */
|
||||
LWIP_ASSERT("pbuf_copy() does not allow packet queues!\n",
|
||||
p->next == NULL);
|
||||
p_from->next == NULL);
|
||||
}
|
||||
/* proceed to next pbuf in original chain */
|
||||
p = p->next;
|
||||
} while (p);
|
||||
if((p_to != NULL) && (p_to->len == p_to->tot_len)) {
|
||||
/* don't copy more than one packet! */
|
||||
LWIP_ASSERT("pbuf_copy() does not allow packet queues!\n",
|
||||
p_to->next == NULL);
|
||||
}
|
||||
} while (p_from);
|
||||
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 1, ("pbuf_copy: end of chain reached.\n"));
|
||||
|
||||
return p_copy;
|
||||
#ifdef LWIP_DEBUG
|
||||
LWIP_ASSERT("shouldbe == copied", shouldbe == copied);
|
||||
#endif
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif /* ARP_QUEUEING */
|
||||
|
@ -34,7 +34,7 @@
|
||||
#define __LWIP_PBUF_H__
|
||||
|
||||
#include "arch/cc.h"
|
||||
|
||||
#include "lwip/err.h"
|
||||
|
||||
#define PBUF_TRANSPORT_HLEN 20
|
||||
#define PBUF_IP_HLEN 20
|
||||
@ -107,7 +107,7 @@ void pbuf_cat(struct pbuf *h, struct pbuf *t);
|
||||
void pbuf_chain(struct pbuf *h, struct pbuf *t);
|
||||
struct pbuf *pbuf_dechain(struct pbuf *p);
|
||||
#if ARP_QUEUEING
|
||||
struct pbuf *pbuf_copy(struct pbuf *f);
|
||||
err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from);
|
||||
#endif
|
||||
|
||||
#endif /* __LWIP_PBUF_H__ */
|
||||
|
@ -864,7 +864,11 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
||||
}
|
||||
if(copy_needed) {
|
||||
/* copy the whole packet into new pbufs */
|
||||
p = pbuf_copy(q);
|
||||
p = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
|
||||
if (pbuf_copy(p, q) != ERR_OK) {
|
||||
pbuf_free(p);
|
||||
p = NULL;
|
||||
}
|
||||
} else {
|
||||
/* referencing the old pbuf is enough */
|
||||
p = q;
|
||||
|
Loading…
Reference in New Issue
Block a user