From eed76e2e5af406336111e599b607940c0f317592 Mon Sep 17 00:00:00 2001
From: david gauchard <gauchard@laas.fr>
Date: Tue, 30 Apr 2019 03:43:48 +0200
Subject: [PATCH 1/3] fix switching to static address with lwip2

For some reason, ip address is not propagated in a visible way for lwip2
when switching to static address (wifi.config()) *after* wifi.begin().

This patch calls lwip-v1.4's netif_set_addr() with the new ip address to set
all things up, just like it is done and right when wifi.begin() is called
after wifi.config().

Also tested when IPv6 is enabled.

fixes #5839
fixes #6024
---
 libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp
index 5c77f97998..5510f57805 100644
--- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp
+++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp
@@ -247,6 +247,13 @@ wl_status_t ESP8266WiFiSTAClass::begin() {
  * @param dns1       Static DNS server 1
  * @param dns2       Static DNS server 2
  */
+
+#if LWIP_VERSION_MAJOR != 1
+#undef netif_set_addr // need to call lwip-v1.4 netif_set_addr()
+extern "C" struct netif* eagle_lwip_getif (int netif_index);
+extern "C" void netif_set_addr (struct netif* netif, ip4_addr_t* ip, ip4_addr_t* netmask, ip4_addr_t* gw);
+#endif
+
 bool ESP8266WiFiSTAClass::config(IPAddress local_ip, IPAddress arg1, IPAddress arg2, IPAddress arg3, IPAddress dns2) {
 
   if(!WiFi.enableSTA(true)) {
@@ -310,6 +317,11 @@ bool ESP8266WiFiSTAClass::config(IPAddress local_ip, IPAddress arg1, IPAddress a
       dns_setserver(1, dns2);
   }
 
+#if LWIP_VERSION_MAJOR != 1
+  // trigger address change by calling lwip-v1.4 api
+  netif_set_addr(eagle_lwip_getif(STATION_IF), &info.ip, &info.netmask, &info.gw);
+#endif
+
   return true;
 }
 

From 6826b42844364cc4c6c9d742ffa96cf93a1ed67e Mon Sep 17 00:00:00 2001
From: David Gauchard <gauchard@laas.fr>
Date: Tue, 30 Apr 2019 14:20:48 +0200
Subject: [PATCH 2/3] add comments

---
 libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp
index 5510f57805..58daa5114c 100644
--- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp
+++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp
@@ -249,7 +249,21 @@ wl_status_t ESP8266WiFiSTAClass::begin() {
  */
 
 #if LWIP_VERSION_MAJOR != 1
-#undef netif_set_addr // need to call lwip-v1.4 netif_set_addr()
+/*
+  About the following call in the end of ESP8266WiFiSTAClass::config():
+      netif_set_addr(eagle_lwip_getif(STATION_IF), &info.ip, &info.netmask, &info.gw);
+
+  With lwip2, it is needed to trigger IP address change.
+      Recall: when lwip2 is enabled, lwip1 api is still used by espressif firmware
+          https://github.com/d-a-v/esp82xx-nonos-linklayer/tree/25d5e8186f710a230221021cba97727dbfdfd953#how-it-works
+
+  We need first to disable the lwIP API redirection for netif_set_addr() so lwip1's call will be linked:
+      https://github.com/d-a-v/esp82xx-nonos-linklayer/blob/25d5e8186f710a230221021cba97727dbfdfd953/glue-lwip/arch/cc.h#L122
+
+  We also need to declare its prototype using ip4_addr_t instead of ip_addr_t because lwIP-1.x never has IPv6.
+  No need to worry about this #undef, this call is only needed in lwip2, and never used in arduino core code.
+ */
+#undef netif_set_addr // need to call lwIP-v1.4 netif_set_addr()
 extern "C" struct netif* eagle_lwip_getif (int netif_index);
 extern "C" void netif_set_addr (struct netif* netif, ip4_addr_t* ip, ip4_addr_t* netmask, ip4_addr_t* gw);
 #endif
@@ -318,7 +332,8 @@ bool ESP8266WiFiSTAClass::config(IPAddress local_ip, IPAddress arg1, IPAddress a
   }
 
 #if LWIP_VERSION_MAJOR != 1
-  // trigger address change by calling lwip-v1.4 api
+  // trigger address change by calling lwIP-v1.4 api
+  // (see explanation above)
   netif_set_addr(eagle_lwip_getif(STATION_IF), &info.ip, &info.netmask, &info.gw);
 #endif
 

From 4b85b7c0148a12da082a0280251259183c8eb89c Mon Sep 17 00:00:00 2001
From: David Gauchard <gauchard@laas.fr>
Date: Tue, 30 Apr 2019 14:29:12 +0200
Subject: [PATCH 3/3] documentation: It is more natural to set an IP address
 before starting WiFi

(.. and not after dhcp has started)
---
 doc/esp8266wifi/station-class.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/esp8266wifi/station-class.rst b/doc/esp8266wifi/station-class.rst
index 245fb60594..7464c3ad84 100644
--- a/doc/esp8266wifi/station-class.rst
+++ b/doc/esp8266wifi/station-class.rst
@@ -135,8 +135,8 @@ The following IP configuration may be provided:
       Serial.println();
 
       Serial.printf("Connecting to %s\n", ssid);
-      WiFi.begin(ssid, password);
       WiFi.config(staticIP, gateway, subnet);
+      WiFi.begin(ssid, password);
       while (WiFi.status() != WL_CONNECTED)
       {
         delay(500);