139 #if LWIP_TCP && TCP_QUEUE_OOSEQ 142 #if LWIP_CHECKSUM_ON_COPY 148 #define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf)) 151 #define PBUF_POOL_BUFSIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE) 153 #if !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ 154 #define PBUF_POOL_IS_EMPTY() 158 #ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL 160 #define PBUF_POOL_FREE_OOSEQ_QUEUE_CALL() do { \ 161 if (tcpip_callback_with_block(pbuf_free_ooseq_callback, NULL, 0) != ERR_OK) { \ 162 SYS_ARCH_PROTECT(old_level); \ 163 pbuf_free_ooseq_pending = 0; \ 164 SYS_ARCH_UNPROTECT(old_level); \ 169 volatile u8_t pbuf_free_ooseq_pending;
170 #define PBUF_POOL_IS_EMPTY() pbuf_pool_is_empty() 184 pbuf_free_ooseq(
void)
187 SYS_ARCH_SET(pbuf_free_ooseq_pending, 0);
189 for (pcb = tcp_active_pcbs; NULL != pcb; pcb = pcb->next) {
190 if (NULL != pcb->ooseq) {
193 tcp_segs_free(pcb->ooseq);
205 pbuf_free_ooseq_callback(
void *arg)
214 pbuf_pool_is_empty(
void)
216 #ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL 217 SYS_ARCH_SET(pbuf_free_ooseq_pending, 1);
221 SYS_ARCH_PROTECT(old_level);
222 queued = pbuf_free_ooseq_pending;
223 pbuf_free_ooseq_pending = 1;
224 SYS_ARCH_UNPROTECT(old_level);
228 PBUF_POOL_FREE_OOSEQ_QUEUE_CALL();
269 struct pbuf *p, *q, *r;
297 LWIP_ASSERT(
"pbuf_alloc: bad pbuf layer", 0);
307 PBUF_POOL_IS_EMPTY();
315 LWIP_ASSERT(
"pbuf_alloc: pbuf p->payload properly aligned",
316 ((mem_ptr_t)p->
payload % MEM_ALIGNMENT) == 0);
321 LWIP_ASSERT(
"check p->payload + p->len does not overflow pbuf",
323 (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED));
324 LWIP_ASSERT(
"PBUF_POOL_BUFSIZE must be bigger than MEM_ALIGNMENT",
334 rem_len = length - p->
len;
336 while (rem_len > 0) {
339 PBUF_POOL_IS_EMPTY();
351 LWIP_ASSERT(
"rem_len < max_u16_t", rem_len < 0xffff);
354 q->
len = LWIP_MIN((u16_t)rem_len, PBUF_POOL_BUFSIZE_ALIGNED);
355 q->
payload = (
void *)((u8_t *)q + SIZEOF_STRUCT_PBUF);
356 LWIP_ASSERT(
"pbuf_alloc: pbuf q->payload properly aligned",
357 ((mem_ptr_t)q->
payload % MEM_ALIGNMENT) == 0);
358 LWIP_ASSERT(
"check p->payload + p->len does not overflow pbuf",
360 (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED));
393 LWIP_ASSERT(
"pbuf_alloc: pbuf->payload properly aligned",
394 ((mem_ptr_t)p->
payload % MEM_ALIGNMENT) == 0);
404 (
"pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.\n",
405 (type ==
PBUF_ROM) ?
"ROM" :
"REF"));
415 LWIP_ASSERT(
"pbuf_alloc: erroneous type", 0);
426 #if LWIP_SUPPORT_CUSTOM_PBUF 445 void *payload_mem, u16_t payload_mem_len)
472 LWIP_ASSERT(
"pbuf_alloced_custom: bad pbuf layer", 0);
482 if (payload_mem != NULL) {
485 p->pbuf.payload = NULL;
488 p->pbuf.len = p->pbuf.tot_len = length;
518 LWIP_ASSERT(
"pbuf_realloc: p != NULL", p != NULL);
519 LWIP_ASSERT(
"pbuf_realloc: sane p->type", p->
type ==
PBUF_POOL ||
538 while (rem_len > q->
len) {
542 LWIP_ASSERT(
"grow < max_u16_t", grow < 0xffff);
546 LWIP_ASSERT(
"pbuf_realloc: q != NULL", q != NULL);
560 LWIP_ASSERT(
"mem_trim returned q == NULL", q != NULL);
567 if (q->
next != NULL) {
588 pbuf_header_impl(
struct pbuf *p, s16_t header_size_increment, u8_t force)
592 u16_t increment_magnitude;
594 LWIP_ASSERT(
"p != NULL", p != NULL);
595 if ((header_size_increment == 0) || (p == NULL)) {
599 if (header_size_increment < 0) {
600 increment_magnitude = (u16_t)-header_size_increment;
602 LWIP_ERROR(
"increment_magnitude <= p->len", (increment_magnitude <= p->
len),
return 1;);
604 increment_magnitude = (u16_t)header_size_increment;
609 LWIP_ASSERT(
"p->type == PBUF_RAM || p->type == PBUF_POOL",
612 LWIP_ASSERT(
"p->payload - increment_magnitude >= p + SIZEOF_STRUCT_PBUF",
613 (u8_t *)p->
payload - increment_magnitude >= (u8_t *)p + SIZEOF_STRUCT_PBUF);
626 if ((u8_t *)p->
payload < (u8_t *)p + SIZEOF_STRUCT_PBUF) {
628 (
"pbuf_header: failed as %p < %p (not enough space for new header size)\n",
629 (
void *)p->
payload, (
void *)((u8_t *)p + SIZEOF_STRUCT_PBUF)));
638 if ((header_size_increment < 0) && (increment_magnitude <= p->
len)) {
641 }
else if ((header_size_increment > 0) && force) {
650 LWIP_ASSERT(
"bad pbuf type", 0);
654 p->
len += header_size_increment;
655 p->
tot_len += header_size_increment;
658 (
void *)payload, (
void *)p->
payload, header_size_increment));
686 return pbuf_header_impl(p, header_size_increment, 0);
696 return pbuf_header_impl(p, header_size_increment, 1);
741 LWIP_ASSERT(
"p != NULL", p != NULL);
744 (
"pbuf_free(p == NULL) was called.\n"));
751 LWIP_ASSERT(
"pbuf_free: sane type",
764 SYS_ARCH_PROTECT(old_level);
766 LWIP_ASSERT(
"pbuf_free: p->ref > 0", p->
ref > 0);
769 SYS_ARCH_UNPROTECT(old_level);
776 #if LWIP_SUPPORT_CUSTOM_PBUF 779 struct pbuf_custom *pc = (
struct pbuf_custom*)p;
780 LWIP_ASSERT(
"pc->custom_free_function != NULL", pc->custom_free_function != NULL);
781 pc->custom_free_function(p);
807 PERF_STOP(
"pbuf_free");
843 SYS_ARCH_INC(p->
ref, 1);
844 LWIP_ASSERT(
"pbuf ref overflow", p->
ref > 0);
863 LWIP_ERROR(
"(h != NULL) && (t != NULL) (programmer violates API)",
864 ((h != NULL) && (t != NULL)),
return;);
867 for (p = h; p->
next != NULL; p = p->
next) {
872 LWIP_ASSERT(
"p->tot_len == p->len (of last pbuf in chain)", p->
tot_len == p->
len);
873 LWIP_ASSERT(
"p->next == NULL", p->
next == NULL);
927 LWIP_ASSERT(
"p->tot_len == p->len + q->tot_len", q->
tot_len == p->
tot_len - p->
len);
939 (
"pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (
void *)q));
944 LWIP_ASSERT(
"p->tot_len == p->len", p->
tot_len == p->
len);
945 return ((tail_gone > 0) ? NULL : q);
969 u16_t offset_to=0, offset_from=0,
len;
972 (
const void*)p_to, (
const void*)p_from));
975 LWIP_ERROR(
"pbuf_copy: target not big enough to hold source", ((p_to != NULL) &&
982 if ((p_to->
len - offset_to) >= (p_from->
len - offset_from)) {
984 len = p_from->
len - offset_from;
987 len = p_to->
len - offset_to;
989 MEMCPY((u8_t*)p_to->
payload + offset_to, (u8_t*)p_from->
payload + offset_from,
len);
992 LWIP_ASSERT(
"offset_to <= p_to->len", offset_to <= p_to->
len);
993 LWIP_ASSERT(
"offset_from <= p_from->len", offset_from <= p_from->len);
994 if (offset_from >= p_from->
len) {
997 p_from = p_from->
next;
999 if (offset_to == p_to->
len) {
1003 LWIP_ERROR(
"p_to != NULL", (p_to != NULL) || (p_from == NULL) ,
return ERR_ARG;);
1006 if ((p_from != NULL) && (p_from->
len == p_from->
tot_len)) {
1008 LWIP_ERROR(
"pbuf_copy() does not allow packet queues!",
1011 if ((p_to != NULL) && (p_to->
len == p_to->
tot_len)) {
1013 LWIP_ERROR(
"pbuf_copy() does not allow packet queues!",
1036 const struct pbuf *p;
1039 u16_t copied_total = 0;
1041 LWIP_ERROR(
"pbuf_copy_partial: invalid buf", (buf != NULL),
return 0;);
1042 LWIP_ERROR(
"pbuf_copy_partial: invalid dataptr", (dataptr != NULL),
return 0;);
1046 if ((buf == NULL) || (dataptr == NULL)) {
1051 for (p = buf; len != 0 && p != NULL; p = p->
next) {
1052 if ((offset != 0) && (offset >= p->
len)) {
1057 buf_copy_len = p->
len - offset;
1058 if (buf_copy_len > len) {
1062 MEMCPY(&((
char*)dataptr)[left], &((
char*)p->
payload)[offset], buf_copy_len);
1063 copied_total += buf_copy_len;
1064 left += buf_copy_len;
1065 len -= buf_copy_len;
1069 return copied_total;
1072 #if LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE 1085 void pbuf_split_64k(
struct pbuf *p,
struct pbuf **rest)
1088 if ((p != NULL) && (p->
next != NULL)) {
1089 u16_t tot_len_front = p->
len;
1094 while ((r != NULL) && ((u16_t)(tot_len_front + r->
len) > tot_len_front)) {
1095 tot_len_front += r->
len;
1105 for (i = p; i != NULL; i = i->
next) {
1107 LWIP_ASSERT(
"tot_len/len mismatch in last pbuf",
1123 static const struct pbuf*
1124 pbuf_skip_const(
const struct pbuf* in, u16_t in_offset, u16_t* out_offset)
1126 u16_t offset_left = in_offset;
1127 const struct pbuf* q = in;
1130 while ((q != NULL) && (q->
len <= offset_left)) {
1131 offset_left -= q->
len;
1134 if (out_offset != NULL) {
1135 *out_offset = offset_left;
1152 const struct pbuf* out = pbuf_skip_const(in, in_offset, out_offset);
1172 u16_t total_copy_len =
len;
1173 u16_t copied_total = 0;
1175 LWIP_ERROR(
"pbuf_take: invalid buf", (buf != NULL),
return ERR_ARG;);
1176 LWIP_ERROR(
"pbuf_take: invalid dataptr", (dataptr != NULL),
return ERR_ARG;);
1177 LWIP_ERROR(
"pbuf_take: buf not large enough", (buf->
tot_len >= len),
return ERR_MEM;);
1179 if ((buf == NULL) || (dataptr == NULL) || (buf->
tot_len < len)) {
1184 for (p = buf; total_copy_len != 0; p = p->
next) {
1185 LWIP_ASSERT(
"pbuf_take: invalid pbuf", p != NULL);
1186 buf_copy_len = total_copy_len;
1187 if (buf_copy_len > p->
len) {
1189 buf_copy_len = p->
len;
1192 MEMCPY(p->
payload, &((
const char*)dataptr)[copied_total], buf_copy_len);
1193 total_copy_len -= buf_copy_len;
1194 copied_total += buf_copy_len;
1196 LWIP_ASSERT(
"did not copy all data", total_copy_len == 0 && copied_total == len);
1214 u16_t target_offset;
1218 if ((q != NULL) && (q->
tot_len >= target_offset + len)) {
1219 u16_t remaining_len =
len;
1220 const u8_t* src_ptr = (
const u8_t*)dataptr;
1222 u16_t first_copy_len = LWIP_MIN(q->
len - target_offset, len);
1223 MEMCPY(((u8_t*)q->
payload) + target_offset, dataptr, first_copy_len);
1224 remaining_len -= first_copy_len;
1225 src_ptr += first_copy_len;
1226 if (remaining_len > 0) {
1252 if (p->
next == NULL) {
1262 LWIP_ASSERT(
"pbuf_copy failed", err ==
ERR_OK);
1267 #if LWIP_CHECKSUM_ON_COPY 1281 pbuf_fill_chksum(
struct pbuf *p, u16_t start_offset,
const void *dataptr,
1282 u16_t
len, u16_t *chksum)
1287 LWIP_ASSERT(
"p != NULL", p != NULL);
1288 LWIP_ASSERT(
"dataptr != NULL", dataptr != NULL);
1289 LWIP_ASSERT(
"chksum != NULL", chksum != NULL);
1290 LWIP_ASSERT(
"len != 0", len != 0);
1292 if ((start_offset >= p->
len) || (start_offset + len > p->
len)) {
1296 dst_ptr = ((
char*)p->
payload) + start_offset;
1297 copy_chksum = LWIP_CHKSUM_COPY(dst_ptr, dataptr, len);
1298 if ((start_offset & 1) != 0) {
1339 const struct pbuf* q = pbuf_skip_const(p, offset, &q_idx);
1342 if ((q != NULL) && (q->
len > q_idx)) {
1343 return ((u8_t*)q->
payload)[q_idx];
1364 if ((q != NULL) && (q->
len > q_idx)) {
1365 ((u8_t*)q->
payload)[q_idx] = data;
1383 u16_t start = offset;
1384 const struct pbuf* q = p;
1388 if(p->
tot_len < (offset + n)) {
1393 while ((q != NULL) && (q->
len <= start)) {
1399 for (i = 0; i < n; i++) {
1402 u8_t b = ((
const u8_t*)s2)[i];
1426 u16_t max = p->
tot_len - mem_len;
1427 if (p->
tot_len >= mem_len + start_offset) {
1428 for (i = start_offset; i <= max; i++) {
1453 if ((substr == NULL) || (substr[0] == 0) || (p->
tot_len == 0xFFFF)) {
1456 substr_len = strlen(substr);
1457 if (substr_len >= 0xFFFF) {
void pbuf_realloc(struct pbuf *p, u16_t new_len)
u16_t pbuf_clen(const struct pbuf *p)
struct pbuf * pbuf_skip(struct pbuf *in, u16_t in_offset, u16_t *out_offset)
void mem_free(void *rmem)
u16_t pbuf_memcmp(const struct pbuf *p, u16_t offset, const void *s2, u16_t n)
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
void pbuf_ref(struct pbuf *p)
#define LWIP_SUPPORT_CUSTOM_PBUF
void memp_free(memp_t type, void *mem)
err_t pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from)
#define LWIP_DBG_LEVEL_SERIOUS
u16_t pbuf_memfind(const struct pbuf *p, const void *mem, u16_t mem_len, u16_t start_offset)
#define SYS_ARCH_DECL_PROTECT(lev)
u8_t pbuf_get_at(const struct pbuf *p, u16_t offset)
err_t pbuf_take_at(struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset)
void * mem_trim(void *rmem, mem_size_t newsize)
u16_t pbuf_strstr(const struct pbuf *p, const char *substr)
void pbuf_put_at(struct pbuf *p, u16_t offset, u8_t data)
void pbuf_chain(struct pbuf *h, struct pbuf *t)
#define SWAP_BYTES_IN_WORD(w)
void pbuf_cat(struct pbuf *h, struct pbuf *t)
struct pbuf * pbuf_dechain(struct pbuf *p)
#define LWIP_DEBUGF(debug, message)
#define LWIP_MEM_ALIGN_SIZE(size)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u16_t pbuf_copy_partial(const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len)
#define LWIP_DBG_LEVEL_WARNING
#define PBUF_FLAG_IS_CUSTOM
#define PBUF_FLAG_TCP_FIN
u8_t pbuf_header_force(struct pbuf *p, s16_t header_size_increment)
#define LWIP_MEM_ALIGN(addr)
#define LWIP_UNUSED_ARG(x)
#define LWIP_CONST_CAST(target_type, val)
u8_t pbuf_free(struct pbuf *p)
void * mem_malloc(mem_size_t size)
#define PBUF_LINK_ENCAPSULATION_HLEN
struct pbuf * pbuf_coalesce(struct pbuf *p, pbuf_layer layer)
void * memp_malloc(memp_t type)
int pbuf_try_get_at(const struct pbuf *p, u16_t offset)