From d36a8a1aa07c8ccb10d4fac3a3b2083c2ced8fab Mon Sep 17 00:00:00 2001
From: Sachin Parekh <sachin.parekh@espressif.com>
Date: Mon, 22 Apr 2019 19:08:44 +0530
Subject: [PATCH] igmp: Option for IGMP Timer to be called ondemand
 (dynamically)

mld6: Option for MLD6 Timer to be called ondemand (dynamically)

diff --git a/src/core/ipv4/igmp.c b/src/core/ipv4/igmp.c
index b655aa3a..0e4395a1 100644
--- a/src/core/ipv4/igmp.c
+++ b/src/core/ipv4/igmp.c
@@ -107,6 +107,10 @@ static void   igmp_send(struct netif *netif, struct igmp_group *group, u8_t type
 static ip4_addr_t     allsystems;
 static ip4_addr_t     allrouters;
 
+#if LWIP_IGMP_TIMER_ONDEMAND
+static bool is_tmr_start = false;
+#endif
+
 /**
  * Initialize the IGMP module
  */
@@ -641,6 +645,9 @@ void
 igmp_tmr(void)
 {
   struct netif *netif;
+#if LWIP_IGMP_TIMER_ONDEMAND
+  bool tmr_restart = false;
+#endif
 
   NETIF_FOREACH(netif) {
     struct igmp_group *group = netif_igmp_data(netif);
@@ -651,10 +658,23 @@ igmp_tmr(void)
         if (group->timer == 0) {
           igmp_timeout(netif, group);
         }
+#if LWIP_IGMP_TIMER_ONDEMAND
+        else {
+          tmr_restart = true;
+        }
+#endif
       }
       group = group->next;
     }
   }
+#if LWIP_IGMP_TIMER_ONDEMAND
+  if (tmr_restart) {
+    sys_timeout(IGMP_TMR_INTERVAL, igmp_tmr, NULL);
+  } else {
+    sys_untimeout(igmp_tmr, NULL);
+    is_tmr_start = false;
+  }
+#endif
 }
 
 /**
@@ -701,6 +721,13 @@ igmp_start_timer(struct igmp_group *group, u8_t max_time)
   if (group->timer == 0) {
     group->timer = 1;
   }
+
+#if LWIP_IGMP_TIMER_ONDEMAND
+  if (!is_tmr_start) {
+    sys_timeout(IGMP_TMR_INTERVAL, igmp_tmr, NULL);
+    is_tmr_start = true;
+  }
+#endif
 }
 
 /**
diff --git a/src/core/ipv6/mld6.c b/src/core/ipv6/mld6.c
index 6387d468..5176915d 100644
--- a/src/core/ipv6/mld6.c
+++ b/src/core/ipv6/mld6.c
@@ -87,6 +87,10 @@ static void mld6_delayed_report(struct mld_group *group, u16_t maxresp);
 static void mld6_send(struct netif *netif, struct mld_group *group, u8_t type);
 
 
+#if LWIP_MLD6_TIMER_ONDEMAND
+static bool is_tmr_start = false;
+#endif
+
 /**
  * Stop MLD processing on interface
  *
@@ -496,6 +500,9 @@ void
 mld6_tmr(void)
 {
   struct netif *netif;
+#if LWIP_MLD6_TIMER_ONDEMAND
+  bool tmr_restart = false;
+#endif
 
   NETIF_FOREACH(netif) {
     struct mld_group *group = netif_mld6_data(netif);
@@ -511,10 +518,23 @@ mld6_tmr(void)
             group->group_state = MLD6_GROUP_IDLE_MEMBER;
           }
         }
+#if LWIP_MLD6_TIMER_ONDEMAND
+        else {
+          tmr_restart = true;
+        }
+#endif
       }
       group = group->next;
     }
   }
+#if LWIP_MLD6_TIMER_ONDEMAND
+  if (tmr_restart) {
+    sys_timeout(MLD6_TMR_INTERVAL, mld6_tmr, NULL);
+  } else {
+    sys_untimeout(mld6_tmr, NULL);
+    is_tmr_start = false;
+  }
+#endif
 }
 
 /**
@@ -547,6 +567,12 @@ mld6_delayed_report(struct mld_group *group, u16_t maxresp_in)
       ((group->timer == 0) || (maxresp < group->timer)))) {
     group->timer = maxresp;
     group->group_state = MLD6_GROUP_DELAYING_MEMBER;
+#if LWIP_MLD6_TIMER_ONDEMAND
+    if (!is_tmr_start) {
+      sys_timeout(MLD6_TMR_INTERVAL, mld6_tmr, NULL);
+      is_tmr_start = true;
+    }
+#endif
   }
 }
 
diff --git a/src/core/timeouts.c b/src/core/timeouts.c
index f37acfec..0b7e155e 100644
--- a/src/core/timeouts.c
+++ b/src/core/timeouts.c
@@ -94,7 +94,7 @@ const struct lwip_cyclic_timer lwip_cyclic_timers[] = {
 #if LWIP_AUTOIP
   {AUTOIP_TMR_INTERVAL, HANDLER(autoip_tmr)},
 #endif /* LWIP_AUTOIP */
-#if LWIP_IGMP
+#if LWIP_IGMP && !LWIP_IGMP_TIMER_ONDEMAND
   {IGMP_TMR_INTERVAL, HANDLER(igmp_tmr)},
 #endif /* LWIP_IGMP */
 #endif /* LWIP_IPV4 */
@@ -106,7 +106,7 @@ const struct lwip_cyclic_timer lwip_cyclic_timers[] = {
 #if LWIP_IPV6_REASS
   {IP6_REASS_TMR_INTERVAL, HANDLER(ip6_reass_tmr)},
 #endif /* LWIP_IPV6_REASS */
-#if LWIP_IPV6_MLD
+#if LWIP_IPV6_MLD && !LWIP_MLD6_TIMER_ONDEMAND
   {MLD6_TMR_INTERVAL, HANDLER(mld6_tmr)},
 #endif /* LWIP_IPV6_MLD */
 #if LWIP_IPV6_DHCP6
diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h
index 10625c72..1287d220 100644
--- a/src/include/lwip/opt.h
+++ b/src/include/lwip/opt.h
@@ -1065,13 +1065,16 @@
  */
 /**
  * LWIP_IGMP==1: Turn on IGMP module.
+ * LWIP_IGMP_TIMER_ONDEMAND==1: Start IGMP Timer only when QUERY is received
  */
 #if !defined LWIP_IGMP || defined __DOXYGEN__
 #define LWIP_IGMP                       0
+#define LWIP_IGMP_TIMER_ONDEMAND        0
 #endif
 #if !LWIP_IPV4
 #undef LWIP_IGMP
 #define LWIP_IGMP                       0
+#define LWIP_IGMP_TIMER_ONDEMAND        0
 #endif
 /**
  * @}
@@ -2524,9 +2527,11 @@
  * LWIP_IPV6_MLD==1: Enable multicast listener discovery protocol.
  * If LWIP_IPV6 is enabled but this setting is disabled, the MAC layer must
  * indiscriminately pass all inbound IPv6 multicast traffic to lwIP.
+ * LWIP_MLD6_TIMER_ONDEMAND==1: Start MLD6 timer only when QUERY packet received
  */
 #if !defined LWIP_IPV6_MLD || defined __DOXYGEN__
 #define LWIP_IPV6_MLD                   LWIP_IPV6
+#define LWIP_MLD6_TIMER_ONDEMAND        0
 #endif
 
 /**
-- 
2.17.2 (Apple Git-113)

