diff --git a/contrib/examples/example_app/lwipopts.h b/contrib/examples/example_app/lwipopts.h index 994460f2e..b4ab028ce 100644 --- a/contrib/examples/example_app/lwipopts.h +++ b/contrib/examples/example_app/lwipopts.h @@ -327,6 +327,7 @@ void lwip_example_app_platform_assert(const char *msg, int line, const char *fil #define ESP_LWIP LWIP_NETCONN_FULLDUPLEX #define ESP_LWIP_IGMP_TIMERS_ONDEMAND ESP_LWIP #define ESP_LWIP_MLD6_TIMERS_ONDEMAND ESP_LWIP +#define ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND ESP_LWIP #define ESP_DNS ESP_LWIP #define ESP_LWIP_ARP ESP_LWIP diff --git a/src/core/ipv4/dhcp.c b/src/core/ipv4/dhcp.c index c09319091..e9712238a 100644 --- a/src/core/ipv4/dhcp.c +++ b/src/core/ipv4/dhcp.c @@ -80,9 +80,24 @@ #include "lwip/etharp.h" #include "lwip/prot/dhcp.h" #include "lwip/prot/iana.h" +#include "lwip/timeouts.h" #include +#if ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND +#include +static bool is_tmr_start = false; +#define ESP_LWIP_DHCP_FINE_TIMER_START_ONCE() if (!is_tmr_start) { \ + sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_fine_timeout_cb, NULL); \ + is_tmr_start = true; } +#define ESP_LWIP_DHCP_FINE_CLOSE() if (is_tmr_start) { \ + sys_untimeout(dhcp_fine_timeout_cb, NULL); \ + is_tmr_start = false; } +#else +#define ESP_LWIP_DHCP_FINE_TIMER_START_ONCE() +#define ESP_LWIP_DHCP_FINE_CLOSE() +#endif /* ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND */ + #ifdef LWIP_HOOK_FILENAME #include LWIP_HOOK_FILENAME #endif @@ -308,6 +323,14 @@ dhcp_dec_pcb_refcount(void) } } +#if ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND +void dhcp_fine_timeout_cb(void *arg) +{ + LWIP_UNUSED_ARG(arg); + dhcp_fine_tmr(); +} +#endif + /** * Back-off the DHCP client (because of a received NAK response). * @@ -368,6 +391,8 @@ dhcp_conflict_callback(struct netif *netif, acd_callback_enum_t state) msecs = 10 * 1000; dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs)); + ESP_LWIP_DHCP_FINE_TIMER_START_ONCE(); + break; case ACD_DECLINE: /* remove IP address from interface @@ -499,6 +524,7 @@ dhcp_select(struct netif *netif) msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000); dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs)); + ESP_LWIP_DHCP_FINE_TIMER_START_ONCE(); return result; } @@ -544,10 +570,15 @@ dhcp_coarse_tmr(void) * A DHCP server is expected to respond within a short period of time. * This timer checks whether an outstanding DHCP request is timed out. */ + void dhcp_fine_tmr(void) { struct netif *netif; + +#if ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND + bool tmr_restart = false; +#endif /* ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND */ /* loop through netif's */ NETIF_FOREACH(netif) { struct dhcp *dhcp = netif_dhcp_data(netif); @@ -556,13 +587,27 @@ dhcp_fine_tmr(void) /* timer is active (non zero), and is about to trigger now */ if (dhcp->request_timeout > 1) { dhcp->request_timeout--; +#if ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND + tmr_restart = true; +#endif } else if (dhcp->request_timeout == 1) { dhcp->request_timeout--; /* { dhcp->request_timeout == 0 } */ LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_fine_tmr(): request timeout\n")); /* this client's request timeout triggered */ dhcp_timeout(netif); +#if ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND + tmr_restart = true; +#endif } +#if ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND + if (tmr_restart) { + sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_fine_timeout_cb, NULL); + } else { + sys_untimeout(dhcp_fine_timeout_cb, NULL); + is_tmr_start = false; + } +#endif } } } @@ -1086,6 +1131,7 @@ dhcp_discover(struct netif *netif) msecs = DHCP_REQUEST_BACKOFF_SEQUENCE(dhcp->tries); dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs)); + ESP_LWIP_DHCP_FINE_TIMER_START_ONCE(); return result; } @@ -1158,6 +1204,7 @@ dhcp_bind(struct netif *netif) /* netif is now bound to DHCP leased address - set this before assigning the address to ensure the callback can use dhcp_supplied_address() */ dhcp_set_state(dhcp, DHCP_STATE_BOUND); + ESP_LWIP_DHCP_FINE_CLOSE(); netif_set_addr(netif, &dhcp->offered_ip_addr, &sn_mask, &gw_addr); /* interface is used by routing now that an address is set */ @@ -1217,6 +1264,7 @@ dhcp_renew(struct netif *netif) msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000); dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs)); + ESP_LWIP_DHCP_FINE_TIMER_START_ONCE(); return result; } @@ -1271,6 +1319,7 @@ dhcp_rebind(struct netif *netif) msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000); dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs)); + ESP_LWIP_DHCP_FINE_TIMER_START_ONCE(); return result; } @@ -1328,6 +1377,7 @@ dhcp_reboot(struct netif *netif) msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000); dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs)); + ESP_LWIP_DHCP_FINE_TIMER_START_ONCE(); return result; } diff --git a/src/core/timeouts.c b/src/core/timeouts.c index c04cc2d18..5ba672c38 100644 --- a/src/core/timeouts.c +++ b/src/core/timeouts.c @@ -89,8 +89,10 @@ const struct lwip_cyclic_timer lwip_cyclic_timers[] = { #endif /* LWIP_ARP */ #if LWIP_DHCP {DHCP_COARSE_TIMER_MSECS, HANDLER(dhcp_coarse_tmr)}, - {DHCP_FINE_TIMER_MSECS, HANDLER(dhcp_fine_tmr)}, #endif /* LWIP_DHCP */ +#if LWIP_DHCP && !ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND + {DHCP_FINE_TIMER_MSECS, HANDLER(dhcp_fine_tmr)}, +#endif /* LWIP_DHCP && !ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND */ #if LWIP_ACD {ACD_TMR_INTERVAL, HANDLER(acd_tmr)}, #endif /* LWIP_ACD */ diff --git a/src/include/lwip/dhcp.h b/src/include/lwip/dhcp.h index b413fa63f..a4d1e7638 100644 --- a/src/include/lwip/dhcp.h +++ b/src/include/lwip/dhcp.h @@ -136,6 +136,9 @@ u8_t dhcp_supplied_address(const struct netif *netif); void dhcp_coarse_tmr(void); /* to be called every half second */ void dhcp_fine_tmr(void); +#if ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND +void dhcp_fine_timeout_cb(void *arg); +#endif #if LWIP_DHCP_GET_NTP_SRV /** This function must exist, in other to add offered NTP servers to diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index c4973bba2..41938ea27 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -498,7 +498,7 @@ * The number of sys timeouts used by the core stack (not apps) * The default number of timeouts is calculated here for all enabled modules. */ -#define LWIP_NUM_SYS_TIMEOUT_INTERNAL (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_ACD + (ESP_LWIP_IGMP_TIMERS_ONDEMAND ? 0 : LWIP_IGMP) + LWIP_DNS + PPP_NUM_TIMEOUTS + (LWIP_IPV6 * (1 + LWIP_IPV6_REASS + (ESP_LWIP_MLD6_TIMERS_ONDEMAND ? 0 : LWIP_IPV6_MLD) + LWIP_IPV6_DHCP6))) +#define LWIP_NUM_SYS_TIMEOUT_INTERNAL (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND ? LWIP_DHCP : 2*LWIP_DHCP) + LWIP_ACD + (ESP_LWIP_IGMP_TIMERS_ONDEMAND ? 0 : LWIP_IGMP) + LWIP_DNS + PPP_NUM_TIMEOUTS + (LWIP_IPV6 * (1 + LWIP_IPV6_REASS + (ESP_LWIP_MLD6_TIMERS_ONDEMAND ? 0 : LWIP_IPV6_MLD) + LWIP_IPV6_DHCP6))) /** * MEMP_NUM_SYS_TIMEOUT: the number of simultaneously active timeouts. diff --git a/test/unit/dhcp/test_dhcp.c b/test/unit/dhcp/test_dhcp.c index 130e01581..8eb442958 100644 --- a/test/unit/dhcp/test_dhcp.c +++ b/test/unit/dhcp/test_dhcp.c @@ -6,6 +6,7 @@ #include "lwip/prot/iana.h" #include "lwip/etharp.h" #include "lwip/inet.h" +#include "lwip/timeouts.h" #include "netif/ethernet.h" #if LWIP_ACD @@ -156,6 +157,9 @@ static void tick_lwip(void) acd_tmr(); #endif if (tick % 5 == 0) { +#if ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND + sys_untimeout(dhcp_fine_timeout_cb, NULL); +#endif dhcp_fine_tmr(); } if (tick % (DHCP_COARSE_TIMER_SECS * 10) == 0) { diff --git a/test/unit/lwipopts.h b/test/unit/lwipopts.h index a8cae3085..6754ede93 100644 --- a/test/unit/lwipopts.h +++ b/test/unit/lwipopts.h @@ -163,6 +163,7 @@ u32_t esp_random(void); #define ESP_LWIP_IGMP_TIMERS_ONDEMAND 1 #define ESP_LWIP_MLD6_TIMERS_ONDEMAND 1 #define DNS_FALLBACK_SERVER_INDEX (DNS_MAX_SERVERS - 1) +#define ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND 1 #else #define ESP_LWIP 0 @@ -170,6 +171,10 @@ u32_t esp_random(void); #define ESP_LWIP_IGMP_TIMERS_ONDEMAND 0 #define ESP_LWIP_MLD6_TIMERS_ONDEMAND 0 +#ifndef ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND +#define ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND 0 +#endif + #endif /* ESP_LWIP */ #endif /* LWIP_HDR_LWIPOPTS_H */