@@ -30,6 +30,7 @@ void esp_schedule();
3030}
3131
3232#include < AddrList.h>
33+ #include < PolledTimeout.h>
3334
3435#define PBUF_ALIGNER_ADJUST 4
3536#define PBUF_ALIGNER (x ) ((void *)((((intptr_t )(x))+3 )&~3 ))
@@ -390,14 +391,39 @@ class UdpContext
390391 return size;
391392 }
392393
394+ void cancelBuffer ()
395+ {
396+ if (_tx_buf_head)
397+ pbuf_free (_tx_buf_head);
398+ _tx_buf_head = 0 ;
399+ _tx_buf_cur = 0 ;
400+ _tx_buf_offset = 0 ;
401+ }
402+
393403 bool send (const ip_addr_t * addr = 0 , uint16_t port = 0 )
404+ {
405+ return trySend (addr, port, /* don't keep buffer */ false ) == ERR_OK;
406+ }
407+
408+ bool sendTimeout (const ip_addr_t * addr, uint16_t port,
409+ esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs)
410+ {
411+ err_t err;
412+ esp8266::polledTimeout::oneShotFastMs timeout (timeoutMs);
413+ while (((err = trySend (addr, port, /* keep buffer on error */ true )) != ERR_OK) && !timeout)
414+ delay (0 );
415+ if (err != ERR_OK)
416+ cancelBuffer (); // get rid of buffer kept on error after timeout
417+ return err == ERR_OK;
418+ }
419+
420+ private:
421+
422+ err_t trySend (const ip_addr_t * addr, uint16_t port, bool keepBufferOnError)
394423 {
395424 size_t data_size = _tx_buf_offset;
396425 pbuf* tx_copy = pbuf_alloc (PBUF_TRANSPORT, data_size, PBUF_RAM);
397- if (!tx_copy){
398- DEBUGV (" failed pbuf_alloc" );
399- }
400- else {
426+ if (tx_copy) {
401427 uint8_t * dst = reinterpret_cast <uint8_t *>(tx_copy->payload );
402428 for (pbuf* p = _tx_buf_head; p; p = p->next ) {
403429 size_t will_copy = (data_size < p->len ) ? data_size : p->len ;
@@ -406,38 +432,32 @@ class UdpContext
406432 data_size -= will_copy;
407433 }
408434 }
409- if (_tx_buf_head)
410- pbuf_free (_tx_buf_head);
411- _tx_buf_head = 0 ;
412- _tx_buf_cur = 0 ;
413- _tx_buf_offset = 0 ;
414- if (!tx_copy){
415- return false ;
416- }
417435
436+ if (!keepBufferOnError)
437+ cancelBuffer ();
438+
439+ if (!tx_copy){
440+ DEBUGV (" failed pbuf_alloc" );
441+ return ERR_MEM;
442+ }
418443
419444 if (!addr) {
420445 addr = &_pcb->remote_ip ;
421446 port = _pcb->remote_port ;
422447 }
423- #ifdef LWIP_MAYBE_XCC
424- uint16_t old_ttl = _pcb->ttl ;
425- if (ip_addr_ismulticast (addr)) {
426- _pcb->ttl = _mcast_ttl;
427- }
428- #endif
448+
429449 err_t err = udp_sendto (_pcb, tx_copy, addr, port);
430450 if (err != ERR_OK) {
431451 DEBUGV (" :ust rc=%d\r\n " , (int ) err);
432452 }
433- #ifdef LWIP_MAYBE_XCC
434- _pcb->ttl = old_ttl;
435- #endif
453+
436454 pbuf_free (tx_copy);
437- return err == ERR_OK;
438- }
439455
440- private:
456+ if (err == ERR_OK)
457+ cancelBuffer (); // no error: get rid of buffer
458+
459+ return err;
460+ }
441461
442462 size_t _processSize (const pbuf* pb)
443463 {
0 commit comments