Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Revision:
119:8e1a7805b801
Parent:
103:9cf35a5b9d56
Child:
132:db2174b36a6d
--- a/ip6/icmp/ndp/rs.c	Sat Jan 26 18:57:27 2019 +0000
+++ b/ip6/icmp/ndp/rs.c	Tue Jan 29 15:07:14 2019 +0000
@@ -5,14 +5,21 @@
 #include "net.h"
 #include "ndp.h"
 #include "ip6.h"
+#include "ip6addr.h"
 #include "slaac.h"
 #include "action.h"
 #include "mac.h"
+#include "mstimer.h"
 
 bool RsTrace = false;
 
 bool RsSendSolicitation = false;
 
+#define MAX_REPEAT_DELAY_TIME_MS 60000
+#define MIN_REPEAT_DELAY_TIME_MS   800
+static uint32_t repeatDelayMsTimer = (uint32_t)-MIN_REPEAT_DELAY_TIME_MS; //Initial value ensures no delay at startup
+static uint32_t delayMs            =            MIN_REPEAT_DELAY_TIME_MS; //Doubles on failure up to max; reset to min whenever an IP address request has been acknowledged
+
 __packed struct header
 {
     uint32_t  reserved;
@@ -39,9 +46,20 @@
 }
 int RsGetWaitingSolicitation(void* pPacket, int* pSize, uint8_t* pType, uint8_t* pCode)
 {
-    if (!RsSendSolicitation) return DO_NOTHING;
-    RsSendSolicitation = false;
-    
+    //Check if time to update
+    if (NdpIsFresh())
+    {
+        delayMs = MIN_REPEAT_DELAY_TIME_MS; //Set the delay time back to minimum
+        return DO_NOTHING;
+    }
+
+    //Limit retries with a backoff delay
+    if (!MsTimerHasElapsed(repeatDelayMsTimer, delayMs)) return DO_NOTHING;        //Don't retry within the delay time
+    delayMs <<= 1;                                                                 //Backoff (double) the delay time after each attempt
+    if (delayMs > MAX_REPEAT_DELAY_TIME_MS) delayMs = MAX_REPEAT_DELAY_TIME_MS;    //Don't go beyond a maximum
+    repeatDelayMsTimer = MsTimerCount;                                             //Start the delay timer
+
+    //Send the renewal request
     *pType = 133; //Router solicitation
     *pCode = 0;