Skip to content

Dependency of soft AP DHCP addresses on selected debug level, 'Generic ESP8266 Module' #2728

Open
@mrwgx3

Description

@mrwgx3

Basic Infos

Hardware

Hardware:     ESP12, Adafruit Huzzah Breakout and Feather Boards  
Core Version: 2.3.0

OS, IDE, and SDK

OS:   Windows 10 Professional and Linux Ubuntu 16.04LTS   
IDE:  1.6.12  
SDK:  1.5.3_16_04_18

Description

While in AP+STA mode, it was observed that DHCP addresses assigned by the AP side sometimes differed from those specified by the network parameters passed in Wifi.softAPConfig(). These variations were traced to the debug level chosen for the 'Generic ESP8266 Module' board setting, with erroneous addresses being generated for levels not containing a 'Wifi' entry. Incorrect addresses were also seen for the 'Adafruit HUZZAH ESP8266' board setting, which doesn't expose any debug levels at all.

Further tests revealed that when a specific DEBUG_WIFI() call is NOT made within Wifi.softAPConfig(), the results of a puzzling (perhaps incomplete) DCHP address calculation are used. With the 'Wifi' flag set, however, the critical DEBUG_WIFI() call is made, and the correct DHCP addresses are somehow calculated and set; where and how is not readily apparent.

Also noted was that some address ranges caused Wifi.softAPConfig() to fail due to the calculated starting/ending DHCP address range being inverted (end > start); an example is included in the attached sketch.

Additional items:

  • Tried the same tests for just AP mode; the results were the same.
  • The title for library file ESP8266WiFiAP.cpp should be changed from "ESP8266WiFiSTA.cpp" to "ESP8266WiFiAP.cpp".

Settings in IDE

Module:          Adafruit HUZZAH ESP8266  
Flash Size:      4MB (3M SPIFFS)  
CPU Frequency:   80Mhz  
Debug Settings:  None presented by IDE  
Module:          Generic ESP8266 Module  
Flash Size:      4MB (3M SPIFFS)  
CPU Frequency:   80Mhz  
Flash Mode:      qio  
Flash Frequency: 40Mhz  
Upload Using:    Disabled or SERIAL  
Reset Method:    nodemcu  
Debug Port:      None or Serial
Debug Level:     None, Core, or Core+Wifi

Sketch Outline

The sketch included at the end of this post is used to:
1. Place the ESP12 in AP + STA mode
2. Configure and start the AP side
3. Statically connect to the home network on the STA side
4. Start a minimal web server to check for connectivity

History

This issue was noticed while developing the attached sketch in 'Generic ESP8266 / Core+Wifi' mode. The debug messages from the soft-AP configuration and startup are:

scandone  
del if0  
mode : softAP(5e:cf:7f:c6:9d:bc)  
bcn 0  
del if1  
usl  
add if1  
dhcp server start:(ip:192.168.4.1,mask:255.255.255.0,gw:192.168.4.1)  
bcn 100  
Configuring as AP+STA  
Setting soft-AP configuration ...  
[APConfig] DHCP IP start: 192.168.4.108    << NOTE THESE ADDRESSES  
[APConfig] DHCP IP end: 192.168.4.208  
Ready  
Setting soft-AP ...   
bcn 0  
del if1  
usl  
add if1  
dhcp server start:(ip:192.168.4.9,mask:255.255.255.248,gw:192.168.4.9)  
bcn 100  
Ready  
Soft-AP IP address = 192.168.4.9  

The expected DHCP starting and ending addresses expected from the sketch's WiFi.softAPConfig( ip:192.168.4.9, gw:192.168.4.9, mask:255.255.255.248 ) call would be 192.168.4.9 and 182.168.4.14; quite different from reported addresses of 192.168.4.108 and 192.168.4.208. A check via an 'ipconfig /all' after connecting to the AP, however, shows all but the subnet mask to be in order:

Wireless LAN adapter Wi-Fi 3:  

   Connection-specific DNS Suffix  . :  
   Description . . . . . . . . . . . : 150Mbps Wireless 802.11bgn Nano USB Adapter  
   Physical Address. . . . . . . . . : xx-xx-xx-xx-xx-xx  
   DHCP Enabled. . . . . . . . . . . : Yes
   Autoconfiguration Enabled . . . . : Yes  
   IPv4 Address. . . . . . . . . . . : 192.168.4.10(Preferred)  
   Subnet Mask . . . . . . . . . . . : 255.255.255.0       << INCORRECT, BUT A KNOWN ISSUE
   ....  
   Default Gateway . . . . . . . . . : 192.168.4.9  
   DHCP Server . . . . . . . . . . . : 192.168.4.9  
   ....  

Both the gateway (192.168.4.9) and wireless adapter (192.168.4.10) were also pingable, and the webserver root response was observed after entering '192.168.4.9/' into a browser. Given that everything seemingly works, it was concluded that the DHCP addresses were mis-reported.

After debugging, the 'Adafruit HUZZAH ESP8266' configuration was selected and the sketch recompiled. Everything matches the prior debug output, except for the now absent [APConfig] starting and ending DHCP messages. An 'ipconfig /all' check, however, revealed the actual starting DHCP address now matched the "mis-reported" starting address seen earlier:

Wireless LAN adapter Wi-Fi 3:  

   Connection-specific DNS Suffix  . :  
   Description . . . . . . . . . . . : 150Mbps Wireless 802.11bgn Nano USB Adapter  
   ....  
   IPv4 Address. . . . . . . . . . . : 192.168.4.108(Preferred)  
   Subnet Mask . . . . . . . . . . . : 255.255.255.0  
   ....  
   Default Gateway . . . . . . . . . : 192.168.4.9  
   DHCP Server . . . . . . . . . . . : 192.168.4.9  
   ....  

The wireless adapter (192.168.4.108) was pingable, but the gateway address (192.168.4.9) was not. The webserver root response was no longer observable as well.

Additional Troubleshooting

The DHCP address calculations are found in ESP8266WiFiAPClass::softAPConfig():

 
    struct dhcps_lease dhcp_lease;              // LINE 202
    IPAddress ip = local_ip;
    ip[3] += 99;
    dhcp_lease.start_ip.addr = static_cast<uint32_t>(ip);
    DEBUG_WIFI("[APConfig] DHCP IP start: %s\n", ip.toString().c_str());

    ip[3] += 100;
    dhcp_lease.end_ip.addr = static_cast<uint32_t>(ip);
    DEBUG_WIFI("[APConfig] DHCP IP end: %s\n", ip.toString().c_str());

    if(!wifi_softap_set_dhcps_lease(&dhcp_lease)) {
        DEBUG_WIFI("[APConfig] wifi_set_ip_info failed!\n");
        ret = false;
    }

The errant '192.168.4.108' address arises from the 'ip[3] += 99' addition, i.e., 99 + 9 = 108.

Given correct DHCP addresses were seen while 'Wifi+Core' debug messages were active, while erroneous ones occured for the 'Huzzah' configuration, all other 'Generic' debug message configurations were checked. Erroneous addresses were observed only when the 'Wifi' debug flag was OFF.

Systematic comment/uncommenting of active DEBUG_WIFI() lines isolated the 1st message line in 'softAPConfig()' as the critical one; commenting this line out while the 'Wifi' debug level was active caused erroneous DHCP addresses. More expermentation showed that the length of the variable arglist to be important:

/**
 * Configure access point
 * @param local_ip      access point IP
 * @param gateway       gateway IP
 * @param subnet        subnet mask
 */
bool ESP8266WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet) {        // LINE 179

//    1) LINE 180, Critical DEBUG_WIFI(), Correct DHCP address when left in
DEBUG_WIFI("[APConfig] local_ip: %s gateway: %s subnet: %s\n", local_ip.toString().c_str(), gateway.toString().c_str(), subnet.toString().c_str());

//    2) Erroneous DHCP address when commented out
//DEBUG_WIFI("[APConfig] local_ip: %s gateway: %s subnet: %s\n", local_ip.toString().c_str(), gateway.toString().c_str(), subnet.toString().c_str());

//    3) Replace line 180 variables with different ones, then change varlist size

//       a) Behaves like original line, OK when in, error when commented out
IPAddress ipa(10,0,0,1);
DEBUG_WIFI("[APConfig] dummy1: %s dummy2: %s dummy3: %s\n", ipa.toString().c_str(), ipa.toString().c_str(), //ipa.toString().c_str()  );

//       b) Remove (1) argument, OK when in, error when commented out
IPAddress ipa(10,0,0,1);
DEBUG_WIFI("[APConfig] dummy1: %s dummy2: %s\n", ipa.toString().c_str(), ipa.toString().c_str() );

//       c) Remove (2) arguments, erroneous address regardless whether present or not
IPAddress ipa(10,0,0,1);
DEBUG_WIFI("[APConfig] dummy1: %s\n", ipa.toString().c_str() );

//    4) Divide original line into (3) separate lines, then see if we get erroneous result as implied by (3c):
DEBUG_WIFI("[APConfig] local_ip: %s ", local_ip.toString().c_str() );
DEBUG_WIFI("gateway: %s ", gateway.toString().c_str() );
DEBUG_WIFI("subnet: %s\n", subnet.toString().c_str() );

// ** Yes: Erroneous DHCP addresses are now always present; may help to isolate the problem **

Lastly, inspection of 'wifi_softap_set_dhcps_lease()' of the LWIP libraries indicated that some IP addresses may cause a 'fail' to be returned by softAPConfig(). To demonstrate this, set the sketch compiler variable 'AP_CFGERR' to a non-zero value and re-compile:

scandone
del if0
mode : softAP(5e:cf:7f:c6:da:a4)
bcn 0
del if1
usl
add if1
dhcp server start:(ip:192.168.4.1,mask:255.255.255.0,gw:192.168.4.1)
bcn 100
Configuring as AP+STA
Setting soft-AP configuration ... 
[APConfig] DHCP IP start: 192.168.4.204     << Addresses are inverted; (start - end) > 0x64, generates the 'fail'
[APConfig] DHCP IP end: 192.168.4.48
[APConfig] wifi_set_ip_info failed!
Failed!
Setting soft-AP ... 
bcn 0
del if1
usl
add if1
dhcp server start:(ip:192.168.4.105,mask:255.255.255.248,gw:192.168.4.105)
bcn 100
Ready
Soft-AP IP address = 192.168.4.105

An 'ipconfig /all' check showed correct DHCP addresses, a result comfirmed again with pings and a webserver root response:

Wireless LAN adapter Wi-Fi 3:

   Connection-specific DNS Suffix  . :
   Description . . . . . . . . . . . : 150Mbps Wireless 802.11bgn Nano USB Adapter
   ....
   IPv4 Address. . . . . . . . . . . : 192.168.4.106(Preferred)
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   ....
   Default Gateway . . . . . . . . . : 192.168.4.105
   DHCP Server . . . . . . . . . . . : 192.168.4.105
   ....

This result, however, is now obtained regardless of debug mode status or comment state of the 1st DEBUG_WIFI line.

Sketch

/* NodeZm Test Module */

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

//---------------------------------------------------------------------------
// Globals

// Home network SSID and password
const char* home_ssid     = "HomeNetwork";
const char* home_password = "xxxxxxxx";

// Soft access point ssid and password
const char * apsf_ssid     = "NodeZm";
const char * apsf_password = "nodeaaaa";
const char * host          = "nodezm";

IPAddress ipnull( 0, 0, 0, 0 );

// Set AP_CFGERR to a non-zero value to see 'softAPConfig()' failure
#define  AP_CFGERR   0
#if (AP_CFGERR != 0)

// AP address which returns an APConfig error
   IPAddress local_IP(192,168,4,105);    // Hex:   C0.A8.04.69
   IPAddress gateway(192,168,4,105);     // ID/BC: 192.168.4.104 / 192.168.4.111
   IPAddress subnet(255,255,255,248);    // Range: 192.168.4.105 - 192.168.4.110

#else

// AP address something other than the default of 192.168.4.1
   IPAddress local_IP(192,168,4,9);      // Hex: C0.A8.04.09
   IPAddress gateway(192,168,4,9);       // ID/BC: 192.168.4.8 / 192.168.4.15
   IPAddress subnet(255,255,255,248);    // Range: 192.168.4.9 - 192.168.4.14

#endif

// Static station address to connect to home network with
IPAddress ipsta( 192,168,1,50 );         // Hex: C0.A8.01.32
IPAddress gwsta( 192,168,1,1 );          // ID/BC: 192.168.1.0 / 192.168.1.255
IPAddress substa( 255,255,255,0 );       // Range: 192.168.1.1 - 192.168.1.254

// Huzzah LED assignments
const int  LedBlu = 2, LedRed = 0, LedOff = 1, LedOn = 0;

ESP8266WebServer server(80);

//---------------------------------------------------------------------------
void handleRoot() {
  
	digitalWrite ( LedBlu, LedOn );
  String message = "Hello from Root\n\n";

	server.send ( 200, "text/html", message );
  digitalWrite ( LedBlu, LedOff );
  
} //handleRoot

//---------------------------------------------------------------------------
void setup ( void ) {
  
  pinMode(LedRed, OUTPUT);         // Red  LED used to indicate network connection 
  pinMode(LedBlu, OUTPUT);         // Blue LED used to indicate server activity
  digitalWrite(LedRed, LedOff);    // Red  LED off for AP connection, on for AP + STA
  digitalWrite(LedBlu, LedOff);    // Blue LED off, no server activity

  Serial.begin(115200);
  while (!Serial) delay(250);      // Wait until Arduino Serial Monitor opens
  Serial.println( " " );
  Serial.println( " " );

  Serial.setDebugOutput(true);     // ? Cryptic WIFI info

// DEBUG: Disable auto-connect, then disconnect WIFI
  WiFi.setAutoConnect( false );
  WiFi.setAutoReconnect( false );
  WiFi.disconnect( true );           // Wifi OFF
  WiFi.softAPdisconnect( false );    // Wifi already OFF  

  Serial.println( "Configuring as AP+STA" );
  WiFi.mode( WIFI_AP_STA );

  Serial.println("Setting soft-AP configuration ... ");
  Serial.println( WiFi.softAPConfig(local_IP, gateway, subnet) ? "Ready" : "Failed!");

  Serial.println("Setting soft-AP ... ");
  bool ok = WiFi.softAP( apsf_ssid, apsf_password );
  Serial.println( ok ? "Ready" : "Failed!" );

  Serial.print("Soft-AP IP address = ");
  Serial.println(WiFi.softAPIP());
  Serial.println( " " );
  
  Serial.print( "Waiting for STA connection... " );
  WiFi.config( ipsta, gwsta, substa );
  WiFi.begin( home_ssid, home_password );
  bool  conn;
  for ( int i = 0; i < 30; i++ )
     {
     delay(500); Serial.print( "." );
     conn = (WiFi.status() == WL_CONNECTED);
     if ( conn ) break;
     } //end-for
   Serial.println( "." );  // End 'dot' feedback

// Connection status
   IPAddress staIP;
   if ( conn )  {

//    Show connection success, get IP address
      digitalWrite(LedRed, LedOn ); 
      staIP = WiFi.localIP();
      Serial.print("STA IP address: ");
      Serial.println( staIP );  // Show IP we're to use 
   
   } else {

//    No network connect
      Serial.println ( "No STA connection " );

   } //end-else

// DEBUG: Set auto-connect flags
  WiFi.setAutoConnect( true );
  WiFi.setAutoReconnect( true );

// Connect handlers and start server
	server.on ( "/", handleRoot );
	server.begin();
	Serial.println ( "HTTP server started" );
 
} //setup

//---------------------------------------------------------------------------
void loop ( void ) {
	server.handleClient();
} //loop

//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

Metadata

Metadata

Assignees

No one assigned

    Labels

    waiting for feedbackWaiting on additional info. If it's not received, the issue may be closed.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions