@@ -187,7 +187,7 @@ class UdpContext
187
187
if (!_rx_buf)
188
188
return 0 ;
189
189
190
- return _rx_buf->len - _rx_buf_offset;
190
+ return _rx_buf->tot_len - _rx_buf_offset;
191
191
}
192
192
193
193
size_t tell () const
@@ -202,7 +202,7 @@ class UdpContext
202
202
}
203
203
204
204
bool isValidOffset (const size_t pos) const {
205
- return (pos <= _rx_buf->len );
205
+ return (pos <= _rx_buf->tot_len );
206
206
}
207
207
208
208
CONST IPAddress& getRemoteAddress () CONST
@@ -238,6 +238,10 @@ class UdpContext
238
238
}
239
239
240
240
auto deleteme = _rx_buf;
241
+
242
+ while (_rx_buf->len != _rx_buf->tot_len )
243
+ _rx_buf = _rx_buf->next ;
244
+
241
245
_rx_buf = _rx_buf->next ;
242
246
243
247
if (_rx_buf)
@@ -274,10 +278,10 @@ class UdpContext
274
278
275
279
int read ()
276
280
{
277
- if (!_rx_buf || _rx_buf_offset >= _rx_buf->len )
281
+ if (!_rx_buf || _rx_buf_offset >= _rx_buf->tot_len )
278
282
return -1 ;
279
283
280
- char c = reinterpret_cast < char *> (_rx_buf-> payload )[ _rx_buf_offset] ;
284
+ char c = pbuf_get_at (_rx_buf, _rx_buf_offset) ;
281
285
_consume (1 );
282
286
return c;
283
287
}
@@ -287,22 +291,28 @@ class UdpContext
287
291
if (!_rx_buf)
288
292
return 0 ;
289
293
290
- size_t max_size = _rx_buf->len - _rx_buf_offset;
294
+ size_t max_size = _rx_buf->tot_len - _rx_buf_offset;
291
295
size = (size < max_size) ? size : max_size;
292
- DEBUGV (" :urd %d, %d, %d\r\n " , size, _rx_buf->len , _rx_buf_offset);
296
+ DEBUGV (" :urd %d, %d, %d\r\n " , size, _rx_buf->tot_len , _rx_buf_offset);
297
+
298
+ void * buf = pbuf_get_contiguous (_rx_buf, dst, size, size, _rx_buf_offset);
299
+ if (!buf)
300
+ return 0 ;
301
+
302
+ if (buf != dst)
303
+ memcpy (dst, buf, size);
293
304
294
- memcpy (dst, reinterpret_cast <char *>(_rx_buf->payload ) + _rx_buf_offset, size);
295
305
_consume (size);
296
306
297
307
return size;
298
308
}
299
309
300
310
int peek () const
301
311
{
302
- if (!_rx_buf || _rx_buf_offset == _rx_buf->len )
312
+ if (!_rx_buf || _rx_buf_offset == _rx_buf->tot_len )
303
313
return -1 ;
304
314
305
- return reinterpret_cast < char *> (_rx_buf-> payload )[ _rx_buf_offset] ;
315
+ return pbuf_get_at (_rx_buf, _rx_buf_offset) ;
306
316
}
307
317
308
318
void flush ()
@@ -311,7 +321,7 @@ class UdpContext
311
321
if (!_rx_buf)
312
322
return ;
313
323
314
- _consume (_rx_buf->len - _rx_buf_offset);
324
+ _consume (_rx_buf->tot_len - _rx_buf_offset);
315
325
}
316
326
317
327
size_t append (const char * data, size_t size)
@@ -432,8 +442,8 @@ class UdpContext
432
442
void _consume (size_t size)
433
443
{
434
444
_rx_buf_offset += size;
435
- if (_rx_buf_offset > _rx_buf->len ) {
436
- _rx_buf_offset = _rx_buf->len ;
445
+ if (_rx_buf_offset > _rx_buf->tot_len ) {
446
+ _rx_buf_offset = _rx_buf->tot_len ;
437
447
}
438
448
}
439
449
@@ -522,6 +532,90 @@ class UdpContext
522
532
reinterpret_cast <UdpContext*>(arg)->_recv (upcb, p, srcaddr, srcport);
523
533
}
524
534
535
+ #if LWIP_VERSION_MAJOR == 1
536
+ /*
537
+ * Code in this conditional block is copied/backported verbatim from
538
+ * LwIP 2.1.2 to provide pbuf_get_contiguous.
539
+ */
540
+
541
+ static const struct pbuf *
542
+ pbuf_skip_const (const struct pbuf *in, u16_t in_offset, u16_t *out_offset)
543
+ {
544
+ u16_t offset_left = in_offset;
545
+ const struct pbuf *pbuf_it = in;
546
+
547
+ /* get the correct pbuf */
548
+ while ((pbuf_it != NULL ) && (pbuf_it->len <= offset_left)) {
549
+ offset_left = (u16_t )(offset_left - pbuf_it->len );
550
+ pbuf_it = pbuf_it->next ;
551
+ }
552
+ if (out_offset != NULL ) {
553
+ *out_offset = offset_left;
554
+ }
555
+ return pbuf_it;
556
+ }
557
+
558
+ u16_t
559
+ pbuf_copy_partial (const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
560
+ {
561
+ const struct pbuf *p;
562
+ u16_t left = 0 ;
563
+ u16_t buf_copy_len;
564
+ u16_t copied_total = 0 ;
565
+
566
+ LWIP_ERROR (" pbuf_copy_partial: invalid buf" , (buf != NULL ), return 0 ;);
567
+ LWIP_ERROR (" pbuf_copy_partial: invalid dataptr" , (dataptr != NULL ), return 0 ;);
568
+
569
+ /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */
570
+ for (p = buf; len != 0 && p != NULL ; p = p->next ) {
571
+ if ((offset != 0 ) && (offset >= p->len )) {
572
+ /* don't copy from this buffer -> on to the next */
573
+ offset = (u16_t )(offset - p->len );
574
+ } else {
575
+ /* copy from this buffer. maybe only partially. */
576
+ buf_copy_len = (u16_t )(p->len - offset);
577
+ if (buf_copy_len > len) {
578
+ buf_copy_len = len;
579
+ }
580
+ /* copy the necessary parts of the buffer */
581
+ MEMCPY (&((char *)dataptr)[left], &((char *)p->payload )[offset], buf_copy_len);
582
+ copied_total = (u16_t )(copied_total + buf_copy_len);
583
+ left = (u16_t )(left + buf_copy_len);
584
+ len = (u16_t )(len - buf_copy_len);
585
+ offset = 0 ;
586
+ }
587
+ }
588
+ return copied_total;
589
+ }
590
+
591
+ void *
592
+ pbuf_get_contiguous (const struct pbuf *p, void *buffer, size_t bufsize, u16_t len, u16_t offset)
593
+ {
594
+ const struct pbuf *q;
595
+ u16_t out_offset;
596
+
597
+ LWIP_ERROR (" pbuf_get_contiguous: invalid buf" , (p != NULL ), return NULL ;);
598
+ LWIP_ERROR (" pbuf_get_contiguous: invalid dataptr" , (buffer != NULL ), return NULL ;);
599
+ LWIP_ERROR (" pbuf_get_contiguous: invalid dataptr" , (bufsize >= len), return NULL ;);
600
+
601
+ q = pbuf_skip_const (p, offset, &out_offset);
602
+ if (q != NULL ) {
603
+ if (q->len >= (out_offset + len)) {
604
+ /* all data in this pbuf, return zero-copy */
605
+ return (u8_t *)q->payload + out_offset;
606
+ }
607
+ /* need to copy */
608
+ if (pbuf_copy_partial (q, buffer, len, out_offset) != len) {
609
+ /* copying failed: pbuf is too short */
610
+ return NULL ;
611
+ }
612
+ return buffer;
613
+ }
614
+ /* pbuf is too short (offset does not fit in) */
615
+ return NULL ;
616
+ }
617
+ #endif
618
+
525
619
private:
526
620
udp_pcb* _pcb;
527
621
pbuf* _rx_buf;
0 commit comments