Create PBUF_RAM copies of pbufs.
Used to queue packets on behalf of the lwIP stack, such as ARP based queueing.
- Note:
- You MUST explicitly use p = pbuf_take(p);
-
Only one packet is copied, no packet queue!
- Parameters:
-
| p_to | pbuf destination of the copy |
| p_from | pbuf source of the copy |
- Returns:
- ERR_OK if pbuf was copied ERR_ARG if one of the pbufs is NULL or p_to is not big enough to hold p_from
Definition at line 829 of file pbuf.c.
Referenced by pbuf_coalesce().
{
u16_t offset_to=0, offset_from=0, len;
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n",
(void*)p_to, (void*)p_from));
LWIP_ERROR("pbuf_copy: target not big enough to hold source", ((p_to != NULL) &&
(p_from != NULL) && (p_to->tot_len >= p_from->tot_len)), return ERR_ARG;);
do
{
LWIP_ASSERT("p_to != NULL", p_to != NULL);
if ((p_to->len - offset_to) >= (p_from->len - offset_from)) {
len = p_from->len - offset_from;
} else {
len = p_to->len - offset_to;
}
MEMCPY((u8_t*)p_to->payload + offset_to, (u8_t*)p_from->payload + offset_from, len);
offset_to += len;
offset_from += len;
LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len);
if (offset_to == p_to->len) {
offset_to = 0;
p_to = p_to->next;
}
LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len);
if (offset_from >= p_from->len) {
offset_from = 0;
p_from = p_from->next;
}
if((p_from != NULL) && (p_from->len == p_from->tot_len)) {
LWIP_ERROR("pbuf_copy() does not allow packet queues!\n",
(p_from->next == NULL), return ERR_VAL;);
}
if((p_to != NULL) && (p_to->len == p_to->tot_len)) {
LWIP_ERROR("pbuf_copy() does not allow packet queues!\n",
(p_to->next == NULL), return ERR_VAL;);
}
} while (p_from);
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n"));
return ERR_OK;
}