/**
* 缩减一个pbuf链到希望的长度
* @参数p:要缩减的pbuf
* @参数new_len:pbuf数据链希望的新长度
*
* pbuf数据链的前几个pbuf内容和长度保持不变,新的最后一个pbuf长度重新定义,pbuf链中
* 其余的pbuf将被释放
*
* @注意:如果pbuf是ROM/REF, 只有pbuf的->tot_len和 ->len区域调整。
* @注意:不能调用一个数据包序列。
*
* @注意:pbuf_realloc不能增加一个pbuf(链)的大小
*/
void
pbuf_realloc(struct pbuf *p, u16_t new_len)
{
struct pbuf *q;
u16_t rem_len; /* 剩余长度 */
s32_t grow;
LWIP_ASSERT("pbuf_realloc: p != NULL", p != NULL);
LWIP_ASSERT("pbuf_realloc: sane p->type", p->type == PBUF_POOL ||
p->type == PBUF_ROM ||
p->type == PBUF_RAM ||
p->type == PBUF_REF);
/* 希望的长度超过当前长度? */
if (new_len >= p->tot_len) {
/* enlarging not yet supported */
return;
}
/* pbuf链增加的长度(new_len - p->tot_len)字节
* (在收缩情况下为负数) */
grow = new_len - p->tot_len;
/* 首先,新pbuf链的长度 */
rem_len = new_len;
q = p;
/* 这个pbuf是否保留在pbuf链里面 */
while (rem_len > q->len) {
/* 新的剩余长度 */
rem_len -= q->len;
/* 新的总长度 */
LWIP_ASSERT("grow < max_u16_t", grow < 0xffff);
/*
* 因为grow不会超过-ffff,所以(u16_t)grow仍为grow的补码,
* q->tot_len += (u16_t)grow;相当于q->tot_len减去grow的绝对值
*/
q->tot_len += (u16_t)grow;
/* 指向链中的下一个pbuf */
q = q->next;
LWIP_ASSERT("pbuf_realloc: q != NULL", q != NULL);
}
/* 现在到达新的最后一个pbuf(in q) */
/* rem_len == pbuf q希望的长度 */
/* 为PBUF_RAM缩减内存分配 */
/* (其他类型值调整长度字段) */
if ((q->type == PBUF_RAM) && (rem_len != q->len)) {
/* reallocate and adjust the length of the pbuf that will be split */
q = (struct pbuf *)mem_trim(q, (u16_t)((u8_t *)q->payload - (u8_t *)q) + rem_len);
LWIP_ASSERT("mem_trim returned q == NULL", q != NULL);
}
/* 为新的最后一个pbuf调整长度字段 */
q->len = rem_len;
q->tot_len = q->len;
/* 链中所有其余的pbufs? */
if (q->next != NULL) {
/* 释放链中所有其余的pbufs */
pbuf_free(q->next);
}
/* q 是链中最后一个数据包 */
q->next = NULL;