From 50cbdc0b92dc38050fb0e1e498b609e0f48501ba Mon Sep 17 00:00:00 2001
From: david gauchard <gauchard@laas.fr>
Date: Mon, 3 Dec 2018 19:15:50 +0100
Subject: [PATCH] update AddrList and examples (#5422)

---
 cores/esp8266/AddrList.h                      | 100 +++++++++++-------
 .../examples/IPv6/IPv6.ino                    |  15 +--
 .../examples/{udp/udp.ino => Udp/Udp.ino}     |   0
 .../httpUpdateSigned/httpUpdateSigned.ino     |   7 +-
 tests/common.sh                               |   4 +-
 tests/run_CI_locally.sh                       |   2 +-
 6 files changed, 80 insertions(+), 48 deletions(-)
 rename libraries/{esp8266 => ESP8266WiFi}/examples/IPv6/IPv6.ino (93%)
 rename libraries/ESP8266WiFi/examples/{udp/udp.ino => Udp/Udp.ino} (100%)

diff --git a/cores/esp8266/AddrList.h b/cores/esp8266/AddrList.h
index 33708eaf5..fd1ff4573 100644
--- a/cores/esp8266/AddrList.h
+++ b/cores/esp8266/AddrList.h
@@ -24,7 +24,7 @@
   for (auto a: addrList)
     out.printf("IF='%s' index=%d legacy=%d IPv4=%d local=%d hostname='%s' addr= %s\n",
                a.iface().c_str(),
-               a.number(),
+               a.ifnumber(),
                a.addr().isLegacy(),
                a.addr().isV4(),
                a.addr().isLocal(),
@@ -65,7 +65,7 @@
           for (auto iface: addrList)
               if ((configured = (   !iface.addr().isV4()
                                  && !iface.addr().isLocal()
-                                 && iface.number() == STATION_IF)))
+                                 && iface.ifnumber() == STATION_IF)))
                   break;
           Serial.print('.');
           delay(500);
@@ -94,28 +94,40 @@ namespace AddressListImplementation
 
 struct netifWrapper
 {
-    netifWrapper(netif * netif) : _netif(netif), _num(-1) {}
-    netifWrapper(const netifWrapper & o) : _netif(o._netif), _num(o._num) {}
+    netifWrapper (netif* netif) : _netif(netif), _num(-1) {}
+    netifWrapper (const netifWrapper& o) : _netif(o._netif), _num(o._num) {}
 
-    netifWrapper& operator=(const netifWrapper & o) {_netif = o._netif; _num = o._num; return *this;}
+    netifWrapper& operator= (const netifWrapper& o)
+    {
+        _netif = o._netif;
+        _num = o._num;
+        return *this;
+    }
 
-    bool equal (const netifWrapper & o) 
+    bool equal(const netifWrapper& o)
     {
         return _netif == o._netif && (!_netif || _num == o._num);
     }
 
+    // address properties
+    IPAddress addr () const         { return ipFromNetifNum(); }
+    bool isLegacy () const          { return _num == 0; }
+    bool isLocal () const           { return addr().isLocal(); }
+    bool isV4 () const              { return addr().isV4(); }
+    bool isV6 () const              { return !addr().isV4(); }
+    String toString() const         { return addr().toString(); }
 
-    bool isLegacy() const         { return _num == 0; }
-    bool isLocal() const          { return addr().isLocal(); }
-    IPAddress addr () const       { return ipFromNetifNum(); }
-    IPAddress netmask () const    { return _netif->netmask; }
-    IPAddress gw () const         { return _netif->gw; }
-    String iface () const         { return String(_netif->name[0]) + _netif->name[1]; }
-    const char* hostname () const { return _netif->hostname?: emptyString.c_str(); }
-    const char* mac () const      { return (const char*)_netif->hwaddr; }
-    int number () const           { return _netif->num; }
+    // related to legacy address (_num=0, ipv4)
+    IPAddress netmask () const      { return _netif->netmask; }
+    IPAddress gw () const           { return _netif->gw; }
 
-    const ip_addr_t* ipFromNetifNum () const 
+    // common to all addresses of this interface
+    String ifname () const          { return String(_netif->name[0]) + _netif->name[1]; }
+    const char* ifhostname () const { return _netif->hostname?: emptyString.c_str(); }
+    const char* ifmac () const      { return (const char*)_netif->hwaddr; }
+    int ifnumber () const           { return _netif->num; }
+
+    const ip_addr_t* ipFromNetifNum () const
     {
 #if LWIP_IPV6
         return _num ? &_netif->ip6_addr[_num - 1] : &_netif->ip_addr;
@@ -124,44 +136,57 @@ struct netifWrapper
 #endif
     }
 
+    // lwIP interface
+    netif* _netif;
 
-    netif * _netif;
+    // address index within interface
+    // 0: legacy address (IPv4)
+    // n>0: (_num-1) is IPv6 index for netif->ip6_addr[]
     int _num;
 };
 
 
-
 class AddressListIterator
 {
 public:
-    AddressListIterator(const netifWrapper &o) : netIf(o) {}
-    AddressListIterator(netif * netif) : netIf(netif) {}
+    AddressListIterator (const netifWrapper& o) : netIf(o) {}
+    AddressListIterator (netif* netif) : netIf(netif)
+    {
+        // This constructor is called with lwIP's global netif_list, or
+        // nullptr.  operator++() is designed to loop through _configured_
+        // addresses.  That's why netIf's _num is initialized to -1 to allow
+        // returning the first usable address to AddressList::begin().
+        (void)operator++();
+    }
 
-    const netifWrapper& operator* () const {return netIf;}
-    const netifWrapper* operator->() const {return &netIf;}
+    const netifWrapper& operator*  () const { return netIf; }
+    const netifWrapper* operator-> () const { return &netIf; }
 
-    bool operator==(AddressListIterator & o) {return netIf.equal(*o);}
-    bool operator!=(AddressListIterator & o) {return !netIf.equal(*o);}
+    bool operator== (AddressListIterator& o) { return netIf.equal(*o); }
+    bool operator!= (AddressListIterator& o) { return !netIf.equal(*o); }
 
-    AddressListIterator & operator= (const AddressListIterator& o) {netIf = o.netIf; return *this; }
+    AddressListIterator& operator= (const AddressListIterator& o) { netIf = o.netIf; return *this; }
 
-    AddressListIterator operator++(int) 
+    AddressListIterator operator++ (int)
     {
         AddressListIterator ret = *this;
-        ++(*this);
+        (void)operator++();
         return ret;
     }
 
-    AddressListIterator & operator++()
+    AddressListIterator& operator++ ()
     {
-        while (netIf._netif) 
+        while (netIf._netif)
         {
-            if (++netIf._num == IF_NUM_ADDRESSES) 
+            if (++netIf._num == IF_NUM_ADDRESSES)
             {
-                netIf = netifWrapper(netIf._netif->next); //num is inited to -1
+                // all addresses from current interface were iterated,
+                // switching to next interface
+                netIf = netifWrapper(netIf._netif->next);
                 continue;
             }
             if (!ip_addr_isany(netIf.ipFromNetifNum()))
+                // found an initialized address
                 break;
         }
         return *this;
@@ -171,24 +196,23 @@ public:
 };
 
 
-
 class AddressList
 {
 public:
   using const_iterator = const AddressListIterator;
 
-  const_iterator begin() const {return const_iterator(netif_list);}
-  const_iterator end()   const {return const_iterator(nullptr);}
+  const_iterator begin () const { return const_iterator(netif_list); }
+  const_iterator   end () const { return const_iterator(nullptr); }
 
 };
 
+inline AddressList::const_iterator begin (const AddressList& a) { return a.begin(); }
+inline AddressList::const_iterator   end (const AddressList& a) { return a.end(); }
 
-inline AddressList::const_iterator begin(const AddressList &a) {return a.begin();}
-inline AddressList::const_iterator end(const AddressList &a) {return a.end();}
 
-} //AddressListImplementation
+} // AddressListImplementation
 
-} //esp8266
+} // esp8266
 
 extern esp8266::AddressListImplementation::AddressList addrList;
 
diff --git a/libraries/esp8266/examples/IPv6/IPv6.ino b/libraries/ESP8266WiFi/examples/IPv6/IPv6.ino
similarity index 93%
rename from libraries/esp8266/examples/IPv6/IPv6.ino
rename to libraries/ESP8266WiFi/examples/IPv6/IPv6.ino
index f1673a189..565710a83 100644
--- a/libraries/esp8266/examples/IPv6/IPv6.ino
+++ b/libraries/ESP8266WiFi/examples/IPv6/IPv6.ino
@@ -66,11 +66,11 @@ void status(Print& out) {
   out.println(F("(with 'telnet <addr> or 'nc -u <addr> 23')"));
   for (auto a : addrList) {
     out.printf("IF='%s' IPv6=%d local=%d hostname='%s' addr= %s",
-               a.iface().c_str(),
-               !a.addr().isV4(),
-               a.addr().isLocal(),
-               a.hostname(),
-               a.addr().toString().c_str());
+               a.ifname().c_str(),
+               a.isV6(),
+               a.isLocal(),
+               a.ifhostname(),
+               a.toString().c_str());
 
     if (a.isLegacy()) {
       out.printf(" / mask:%s / gw:%s",
@@ -79,6 +79,7 @@ void status(Print& out) {
     }
 
     out.println();
+
   }
 
   // lwIP's dns client will ask for IPv4 first (by default)
@@ -96,12 +97,14 @@ void setup() {
   Serial.println();
   Serial.println(ESP.getFullVersion());
 
+  Serial.printf("IPV6 is%s enabled\n", LWIP_IPV6 ? emptyString.c_str() : " NOT");
+
   WiFi.mode(WIFI_STA);
   WiFi.begin(STASSID, STAPSK);
 
   status(Serial);
 
-#if 0
+#if 0 // 0: legacy connecting loop - 1: wait for IPv6
 
   // legacy loop (still valid with IPv4 only)
 
diff --git a/libraries/ESP8266WiFi/examples/udp/udp.ino b/libraries/ESP8266WiFi/examples/Udp/Udp.ino
similarity index 100%
rename from libraries/ESP8266WiFi/examples/udp/udp.ino
rename to libraries/ESP8266WiFi/examples/Udp/Udp.ino
diff --git a/libraries/ESP8266httpUpdate/examples/httpUpdateSigned/httpUpdateSigned.ino b/libraries/ESP8266httpUpdate/examples/httpUpdateSigned/httpUpdateSigned.ino
index b503c1d5b..e196ef641 100644
--- a/libraries/ESP8266httpUpdate/examples/httpUpdateSigned/httpUpdateSigned.ino
+++ b/libraries/ESP8266httpUpdate/examples/httpUpdateSigned/httpUpdateSigned.ino
@@ -21,6 +21,11 @@
 #include <ESP8266HTTPClient.h>
 #include <ESP8266httpUpdate.h>
 
+#ifndef STASSID
+#define STASSID "your-ssid"
+#define STAPSK  "your-password"
+#endif
+
 ESP8266WiFiMulti WiFiMulti;
 
 #define MANUAL_SIGNING 0
@@ -66,7 +71,7 @@ void setup() {
   }
 
   WiFi.mode(WIFI_STA);
-  WiFiMulti.addAP("SSID", "PASS");
+  WiFiMulti.addAP(STASSID, STAPSK);
 
   #if MANUAL_SIGNING
   signPubKey = new BearSSL::PublicKey(pubkey);
diff --git a/tests/common.sh b/tests/common.sh
index b256f4ece..5fbe24506 100755
--- a/tests/common.sh
+++ b/tests/common.sh
@@ -116,8 +116,8 @@ function install_ide()
         debug_flags="-DDEBUG_ESP_PORT=Serial -DDEBUG_ESP_SSL -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_ESP_OOM"
     fi
     # Set custom warnings for all builds (i.e. could add -Wextra at some point)
-    echo "compiler.c.extra_flags=-Wall -Wextra -Werror $debug_flags" > esp8266/platform.local.txt
-    echo "compiler.cpp.extra_flags=-Wall -Wextra -Werror $debug_flags" >> esp8266/platform.local.txt
+    echo "compiler.c.extra_flags=-Wall -Wextra -Werror -DLWIP_IPV6=0 $debug_flags" > esp8266/platform.local.txt
+    echo "compiler.cpp.extra_flags=-Wall -Wextra -Werror -DLWIP_IPV6=0 $debug_flags" >> esp8266/platform.local.txt
     echo -e "\n----platform.local.txt----"
     cat esp8266/platform.local.txt
     echo -e "\n----\n"
diff --git a/tests/run_CI_locally.sh b/tests/run_CI_locally.sh
index a080f3a3d..7f28ab706 100755
--- a/tests/run_CI_locally.sh
+++ b/tests/run_CI_locally.sh
@@ -33,7 +33,7 @@ if [ -d ${TMPCI} ]; then
 	echo ""
 	echo " -- updating CI directory in ${TMPCI} --"
 	echo ""
-	(cd ${TMPCI}; git checkout ${branch}; git pull)
+        (cd ${TMPCI}; git checkout master; git branch -D ${branch} || true; git checkout -b ${branch}; git pull origin ${branch})
 else
 	echo ""
 	echo " -- installing CI directory in ${TMPCI} --"