-->
Page 1 of 1

Loading captive portal page from SD Card

PostPosted: Wed Feb 01, 2017 7:28 am
by dalvyk
I combined two different codes together, a captive portal and a SD card webserver. I encountered a problem which the website in the SD card doesn't load when I connect to the AP (captive portal page). Here's the code..

Code: Select all#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include "./DNSServer.h"
#include <SPI.h>
#include <SD.h>

const byte        DNS_PORT = 53;          // Capture DNS requests on port 53
IPAddress         apIP(10, 10, 10, 1);    // Private network for server
DNSServer         dnsServer;              // Create the DNS object
ESP8266WebServer server(80);
String responseHTML = ""
                      "<html><head><title>Captive Portal Test</title>"
                      "<style>html,body{margin:0;height:100%;overflow:hidden;}"
                      "img{ min-height:100%; min-width:100%;height:auto;width:auto;"
                      "position:absolute;top:-100%; bottom:-100%;left:-100%; right:-100%;"
                      "margin:auto;}</style></head><body><img src='test.png' /><h1>TEST</h1></body></html>";


static bool hasSD = false;
File uploadFile;

void returnOK() {
  server.send(200, "text/plain", "");
}

void returnFail(String msg) {
  server.send(500, "text/plain", msg + "\r\n");
}

bool loadFromSdCard(String path) {
  String dataType = "text/plain";
  if (path.endsWith("/")) path += "index.htm";
  if (path.endsWith(".src")) path = path.substring(0, path.lastIndexOf("."));
  else if (path.endsWith(".htm")) dataType = "text/html";
  else if (path.endsWith(".css")) dataType = "text/css";
  else if (path.endsWith(".js")) dataType = "application/javascript";
  else if (path.endsWith(".png")) dataType = "image/png";
  else if (path.endsWith(".gif")) dataType = "image/gif";
  else if (path.endsWith(".jpg")) dataType = "image/jpeg";
  else if (path.endsWith(".ico")) dataType = "image/x-icon";
  else if (path.endsWith(".xml")) dataType = "text/xml";
  else if (path.endsWith(".pdf")) dataType = "application/pdf";
  else if (path.endsWith(".zip")) dataType = "application/zip";

  File dataFile = SD.open(path.c_str());
  if (dataFile.isDirectory()) {
    path += "/index.htm";
    dataType = "text/html";
    dataFile = SD.open(path.c_str());
  }

  if (!dataFile)
    return false;

  if (server.hasArg("download")) dataType = "application/octet-stream";

  if (server.streamFile(dataFile, dataType) != dataFile.size()) {
  }

  dataFile.close();
  return true;
}

void handleNotFound() {
  if (hasSD && loadFromSdCard(server.uri())) return;
  String message = "SDCARD Not Detected\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " NAME:" + server.argName(i) + "\n VALUE:" + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
}

void setup(void) {
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP("TEST AP");
  dnsServer.start(DNS_PORT, "*", apIP);
  //PROBLEM HERE/
  server.onNotFound([]() {
  server.send(200, "text/html", responseHTML);
  });

  server.begin();

  if (SD.begin(SS)) {
    hasSD = true;
  }
}

void loop(void) {
  dnsServer.processNextRequest();
  server.handleClient();
}

This code replies the "responseHTML" as a Captive portal page which immediately pop-ups when I connect to the AP:
Code: Select allserver.onNotFound([]() {
      server.send(200, "text/html", responseHTML);
      });

The void handleNotFound() handles the page/file request from the browser but if I use it on
Code: Select allserver.onNotFound(handleNotFound);

the captive portal won't show but if I type the server address 10.10.10.1, the page will appear. What seems to be the problem?

Re: Loading captive portal page from SD Card

PostPosted: Thu Feb 02, 2017 12:46 am
by RichardS
So I am playing with Captive portals also and I can get redirects with Andoid phones and tablets, but not PC and Chrome, I get a "This site can’t be reached The connection was reset." messages.... any ideas? might be related.

RichardS

Re: Loading captive portal page from SD Card

PostPosted: Sat Feb 04, 2017 5:44 pm
by g6ejd
have you tried putting in some serial.print diagnostics statements in the code. Does it get to the handlenotfound event handler when forced to with an error? Doe it have any arguments? If you print out message to the serial port, does it look correctly formatted?

There is a problem with the server implementation in that if there is no input page on first connect then no inputs are received through .arg elements. I don't know why. So what I do is have my server e.g. server.on("/", SystemSetup); be initialised through a pseudo set-up page that sends an input form back to the client, then thereafter everything works OK. I think dev./fault fixing on the ESP8266 platform has halted in favour of the ESP32. See example here: https://github.com/G6EJD/ESP8266_WU_Wea ... isplay.ino