Skip to content

Adding "captive portal" functionality to EspBootstrap::run() #5

@jostsalathe

Description

@jostsalathe

I thought that the functionality that can often be seen on public WiFi networks where you are automatically directed to a login page when connecting to that network would be quite useful for the EspBootstrap use case.

During searching for solutions I found out that this is apparently called a "captive portal" and that it can be implemented by having a DNS server on the Access Point like it is done here: https://github.com/125K/ESP8266-Captive-Portal/blob/master/WiFi_Captive_Portal.ino

I just tried adding the DNS server to EspBootstrapDict::doRun() like so:

#include <Arduino.h>
#include <DNSServer.h> //============================================= ADDED THIS
#include <EspBootstrapBase.h>
#include <Dictionary.h>

/*[...]*/

int8_t EspBootstrapDict::doRun() {

  String ssid(SSID_PREFIX);
  const IPAddress   APIP   (10, 1, 1, 1);
  const IPAddress   APMASK (255, 255, 255, 0);

  WiFi.disconnect();
  WiFi.mode(WIFI_AP);

  ssid += WiFi.macAddress();
  ssid.replace(":", "");
  ssid.toLowerCase();
//#if defined( ARDUINO_ARCH_ESP8266 )
//  ssid += String(ESP.getChipId(), HEX);
//#endif
#if defined( ARDUINO_ARCH_ESP32 )
//  ssid += String((uint32_t)( ESP.getEfuseMac() & 0xFFFFFFFFL ), HEX);
  WiFi.softAP( ssid.c_str());
  delay(50);
#endif

  WiFi.softAPConfig(APIP, APIP, APMASK);
  delay(50);
  WiFi.softAP( ssid.c_str());
  yield();

  DNSServer dnsServer; //============================================= ADDED THIS
  iServer = new WebServer(80);
  if (iServer == NULL) return BOOTSTRAP_ERR;

  dnsServer.start(53, "*", APIP); // DNS spoofing (Only for HTTP) //== ADDED THIS

  iServer->on("/submit.html", __espbootstrap_handlesubmit);
  iServer->onNotFound(__espbootstrap_handleroot);

  iAllDone = false;
  iServer->begin();

  uint32_t timeNow = millis();
  while (!iAllDone && !iCancelAP) {
    dnsServer.processNextRequest(); //================================ ADDED THIS
    iServer->handleClient();
    if ( millis() - timeNow > iTimeout ) {
        iServer->stop();
        iServer->close();
        delete iServer;
        iServer = NULL;
        return BOOTSTRAP_TIMEOUT;
    }
    delay(10);
//    yield();
  }

  iServer->stop();
  iServer->close();
  delete iServer;
  iServer = NULL;
  return (iCancelAP ? BOOTSTRAP_CANCEL: BOOTSTRAP_OK);
}

It worked just fine when connecting with my smartphone! My PC probably didn't do it because it already has a wired connection with another DNS Server answering.

I don't know enough about the structure of the EspBootstrap library but I would be toatally stoked if this feature would find its way into it since I think that it adds a really nice step to streamlining the setup process for devices.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions