@@ -47,6 +47,7 @@ class UdpContext
47
47
, _rx_buf(0 )
48
48
, _first_buf_taken(false )
49
49
, _rx_buf_offset(0 )
50
+ , _rx_buf_size(0 )
50
51
, _refcnt(0 )
51
52
, _tx_buf_head(0 )
52
53
, _tx_buf_cur(0 )
@@ -74,6 +75,7 @@ class UdpContext
74
75
pbuf_free (_rx_buf);
75
76
_rx_buf = 0 ;
76
77
_rx_buf_offset = 0 ;
78
+ _rx_buf_size = 0 ;
77
79
}
78
80
}
79
81
@@ -202,12 +204,36 @@ class UdpContext
202
204
_on_rx = handler;
203
205
}
204
206
207
+ #ifdef DEBUG_ESP_CORE
208
+ // this helper is ready to be used when debugging UDP
209
+ void printChain (const pbuf* pb, const char * msg, size_t n) const
210
+ {
211
+ // printf the pb pbuf chain, bufferred and all at once
212
+ char buf[128 ];
213
+ int l = snprintf (buf, sizeof (buf), " UDP: %s %u: " , msg, n);
214
+ while (pb)
215
+ {
216
+ l += snprintf (&buf[l], sizeof (buf) -l, " %p(H=%d,%d<=%d)-" ,
217
+ pb, pb->flags == PBUF_HELPER_FLAG, pb->len , pb->tot_len );
218
+ pb = pb->next ;
219
+ }
220
+ l += snprintf (&buf[l], sizeof (buf) - l, " (end)" );
221
+ DEBUGV (" %s\n " , buf);
222
+ }
223
+ #else
224
+ void printChain (const pbuf* pb, const char * msg) const
225
+ {
226
+ (void )pb;
227
+ (void )msg;
228
+ }
229
+ #endif
230
+
205
231
size_t getSize () const
206
232
{
207
233
if (!_rx_buf)
208
234
return 0 ;
209
235
210
- return _rx_buf-> tot_len - _rx_buf_offset;
236
+ return _rx_buf_size - _rx_buf_offset;
211
237
}
212
238
213
239
size_t tell () const
@@ -222,7 +248,7 @@ class UdpContext
222
248
}
223
249
224
250
bool isValidOffset (const size_t pos) const {
225
- return (pos <= _rx_buf-> tot_len );
251
+ return (pos <= _rx_buf_size );
226
252
}
227
253
228
254
netif* getInputNetif () const
@@ -262,47 +288,54 @@ class UdpContext
262
288
return true ;
263
289
}
264
290
291
+ // We have interleaved informations on addresses within received pbuf chain:
292
+ // (before ipv6 code we had: (data-pbuf) -> (data-pbuf) -> (data-pbuf) -> ... in the receiving order)
293
+ // Now: (address-info-pbuf -> chained-data-pbuf [-> chained-data-pbuf...]) ->
294
+ // (chained-address-info-pbuf -> chained-data-pbuf [-> chained...]) -> ...
295
+ // _rx_buf is currently adressing a data pbuf,
296
+ // in this function it is going to be discarded.
297
+
265
298
auto deleteme = _rx_buf;
266
299
267
- while (_rx_buf->len != _rx_buf->tot_len )
300
+ // forward in the chain until next address-info pbuf or end of chain
301
+ while (_rx_buf && _rx_buf->flags != PBUF_HELPER_FLAG)
268
302
_rx_buf = _rx_buf->next ;
269
303
270
- _rx_buf = _rx_buf->next ;
271
-
272
304
if (_rx_buf)
273
305
{
274
- if (_rx_buf->flags == PBUF_HELPER_FLAG)
275
- {
276
- // we have interleaved informations on addresses within reception pbuf chain:
277
- // before: (data-pbuf) -> (data-pbuf) -> (data-pbuf) -> ... in the receiving order
278
- // now: (address-info-pbuf -> data-pbuf) -> (address-info-pbuf -> data-pbuf) -> ...
306
+ assert (_rx_buf->flags == PBUF_HELPER_FLAG);
279
307
280
- // so the first rx_buf contains an address helper,
281
- // copy it to "current address"
282
- auto helper = (AddrHelper*)PBUF_ALIGNER (_rx_buf->payload );
283
- _currentAddr = *helper;
308
+ // copy address helper to "current address"
309
+ auto helper = (AddrHelper*)PBUF_ALIGNER (_rx_buf->payload );
310
+ _currentAddr = *helper;
284
311
285
- // destroy the helper in the about-to-be-released pbuf
286
- helper->~AddrHelper ();
312
+ // destroy the helper in the about-to-be-released pbuf
313
+ helper->~AddrHelper ();
287
314
288
- // forward in rx_buf list, next one is effective data
289
- // current (not ref'ed) one will be pbuf_free'd with deleteme
290
- _rx_buf = _rx_buf-> next ;
291
- }
315
+ // forward in rx_buf list, next one is effective data
316
+ // current (not ref'ed) one will be pbuf_free'd
317
+ // with the 'deleteme' pointer above
318
+ _rx_buf = _rx_buf-> next ;
292
319
293
320
// this rx_buf is not nullptr by construction,
321
+ assert (_rx_buf);
294
322
// ref'ing it to prevent release from the below pbuf_free(deleteme)
323
+ // (ref counter prevents release and will be decreased by pbuf_free)
295
324
pbuf_ref (_rx_buf);
296
325
}
326
+
327
+ // release in chain previous data, and if any:
328
+ // current helper, but not start of current data
297
329
pbuf_free (deleteme);
298
330
299
331
_rx_buf_offset = 0 ;
332
+ _rx_buf_size = _processSize (_rx_buf);
300
333
return _rx_buf != nullptr ;
301
334
}
302
335
303
336
int read ()
304
337
{
305
- if (!_rx_buf || _rx_buf_offset >= _rx_buf-> tot_len )
338
+ if (!_rx_buf || _rx_buf_offset >= _rx_buf_size )
306
339
return -1 ;
307
340
308
341
char c = pbuf_get_at (_rx_buf, _rx_buf_offset);
@@ -315,9 +348,9 @@ class UdpContext
315
348
if (!_rx_buf)
316
349
return 0 ;
317
350
318
- size_t max_size = _rx_buf-> tot_len - _rx_buf_offset;
351
+ size_t max_size = _rx_buf_size - _rx_buf_offset;
319
352
size = (size < max_size) ? size : max_size;
320
- DEBUGV (" :urd %d, %d, %d\r\n " , size, _rx_buf-> tot_len , _rx_buf_offset);
353
+ DEBUGV (" :urd %d, %d, %d\r\n " , size, _rx_buf_size , _rx_buf_offset);
321
354
322
355
void * buf = pbuf_get_contiguous (_rx_buf, dst, size, size, _rx_buf_offset);
323
356
if (!buf)
@@ -333,7 +366,7 @@ class UdpContext
333
366
334
367
int peek () const
335
368
{
336
- if (!_rx_buf || _rx_buf_offset == _rx_buf-> tot_len )
369
+ if (!_rx_buf || _rx_buf_offset == _rx_buf_size )
337
370
return -1 ;
338
371
339
372
return pbuf_get_at (_rx_buf, _rx_buf_offset);
@@ -345,7 +378,7 @@ class UdpContext
345
378
if (!_rx_buf)
346
379
return ;
347
380
348
- _consume (_rx_buf-> tot_len - _rx_buf_offset);
381
+ _consume (_rx_buf_size - _rx_buf_offset);
349
382
}
350
383
351
384
size_t append (const char * data, size_t size)
@@ -429,6 +462,14 @@ class UdpContext
429
462
430
463
private:
431
464
465
+ size_t _processSize (const pbuf* pb)
466
+ {
467
+ size_t ret = 0 ;
468
+ for (; pb && pb->flags != PBUF_HELPER_FLAG; pb = pb->next )
469
+ ret += pb->len ;
470
+ return ret;
471
+ }
472
+
432
473
void _reserve (size_t size)
433
474
{
434
475
const size_t pbuf_unit_size = 128 ;
@@ -466,8 +507,8 @@ class UdpContext
466
507
void _consume (size_t size)
467
508
{
468
509
_rx_buf_offset += size;
469
- if (_rx_buf_offset > _rx_buf-> tot_len ) {
470
- _rx_buf_offset = _rx_buf-> tot_len ;
510
+ if (_rx_buf_offset > _rx_buf_size ) {
511
+ _rx_buf_offset = _rx_buf_size ;
471
512
}
472
513
}
473
514
@@ -476,6 +517,7 @@ class UdpContext
476
517
{
477
518
(void ) upcb;
478
519
// check receive pbuf chain depth
520
+ // optimization path: cache the pbuf chain length
479
521
{
480
522
pbuf* p;
481
523
int count = 0 ;
@@ -488,6 +530,7 @@ class UdpContext
488
530
return ;
489
531
}
490
532
}
533
+
491
534
#if LWIP_VERSION_MAJOR == 1
492
535
#define TEMPDSTADDR (¤t_iphdr_dest)
493
536
#define TEMPINPUTNETIF (current_netif)
@@ -541,6 +584,7 @@ class UdpContext
541
584
_first_buf_taken = false ;
542
585
_rx_buf = pb;
543
586
_rx_buf_offset = 0 ;
587
+ _rx_buf_size = pb->tot_len ;
544
588
}
545
589
546
590
if (_on_rx) {
@@ -648,6 +692,7 @@ class UdpContext
648
692
pbuf* _rx_buf;
649
693
bool _first_buf_taken;
650
694
size_t _rx_buf_offset;
695
+ size_t _rx_buf_size;
651
696
int _refcnt;
652
697
pbuf* _tx_buf_head;
653
698
pbuf* _tx_buf_cur;
0 commit comments