B4R Question Captive Portal with ESP8266 ??

Alberto Iglesias

Well-Known Member
Licensed User
Longtime User

Alberto Iglesias

Well-Known Member
Licensed User
Longtime User
No no, the idea is show to the user, just after connect with ESP8266 to configure the wifi, a simple webpage to explain the instructions.

in this link you explain how, right? but the end user don't know.
https://www.b4x.com/android/forum/threads/esp8266-wifi-remote-configuration.68596/

Example:
After connect this network (this is an esp8266 hotspot)


upload_2019-12-2_7-49-9.png



and then AUTOMATICALLY show this page:


upload_2019-12-2_7-49-34.png
 
Last edited:
Upvote 0

Alberto Iglesias

Well-Known Member
Licensed User
Longtime User
@Erel, I understand this configurator is a good solution to configure inside the settings on ESP device, but also, we will need 2 devices to to that, 1 ESP and another one (B4J, B4i or B4A) app.

The idea is just popup the webpage after the connection and in this page we can have the fields like your configurator.

Is possible to make any webpage popup? or is impossible?
 
Upvote 0

Alberto Iglesias

Well-Known Member
Licensed User
Longtime User
Hi Alberto,

This library is probably what you need. It will try to connect to an access point and if it can't then it makes ESP as an access point with a captive portal to configure the network.

https://github.com/tzapu/WiFiManager

But I don't know how easy it can be to port it to B4R.

I already checked this library , probably this will help a lot with this. I don't know is @Erel can implement this.

or maybe use the esp8266extra library

https://www.b4x.com/android/forum/threads/esp8266extras-library.72186/
 
Upvote 0

Alberto Iglesias

Well-Known Member
Licensed User
Longtime User
Hi Alberto,

This library is probably what you need. It will try to connect to an access point and if it can't then it makes ESP as an access point with a captive portal to configure the network.

https://github.com/tzapu/WiFiManager

But I don't know how easy it can be to port it to B4R.


this is exactly what we need, but need to port to B4R, @Erel , do you thing is too complicate to do that?

And this can be super usefull for a lot of aplications, like paid Hotspot, like hotel hotspots, etc


687474703a2f2f692e696d6775722e636f6d2f595076573965716c2e706e67
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
There's one thing bothering me…. You want that the connected device (laptop, tablet, phone, etc) AUTOMATICALLY opens the browser once the connection to the esp is established?
I don't think that to be possible!
What you can do is, once the connected device achieves a connection to the esp, WHEN it tries to navigate somewhere, to "catch" it and show your onw page… or the user needs to know that he must access the esp to be presented with the page you need to present!
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
Actually, No! what they do is, once you have established a connection to the hotspot, it will filter all your destination browsing, and if you haven't yet connected your SESSION, then show you a page to do so.
I've never seen an external device highjack a client browser, and am pretty sure it can't/shouldn't be done!
 
Upvote 0

Alberto Iglesias

Well-Known Member
Licensed User
Longtime User
This is a sample I made with my ESP8266, but in native code, not in B4R, the goal is create some library to do the same with B4R.



and this is the code I used for this sample

B4X:
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <FS.h>
#define DBG_OUTPUT_PORT Serial
const byte DNS_PORT = 53;
const char *ssid = "B4X - Captive Portal";
IPAddress apIP(192, 168, 1, 1);
DNSServer dnsServer;
ESP8266WebServer webServer(80);
void setup() {
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP(ssid);
  // if DNSServer is started with "*" for domain name, it will reply with
  // provided IP to all DNS request
  dnsServer.start(DNS_PORT, "*", apIP);
  //start debug port
  DBG_OUTPUT_PORT.begin(115200);
  DBG_OUTPUT_PORT.print("\n");
  DBG_OUTPUT_PORT.setDebugOutput(true);
  SPIFFS.begin();
  //redirect all traffic to index.html
  webServer.onNotFound([]() {
    if(!handleFileRead(webServer.uri()))
    {
   
      const char *metaRefreshStr = "<!DOCTYPE html PUBLIC \"-\/\/W3C\/\/DTD XHTML 1.0 Transitional\/\/EN\" \"http:\/\/www.w3.org\/TR\/xhtml1\/DTD\/xhtml1-transitional.dtd\">\r\n<html xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\" >\r\n<head>\r\n    <title><\/title>\r\n    <style type=\"text\/css\">\r\n        .style1\r\n        {\r\n            font-family: Arial, Helvetica, sans-serif;\r\n            font-weight: bold;\r\n        }\r\n    <\/style>\r\n<\/head>\r\n<body>\r\n\r\n    <p class=\"style1\">\r\n        This page was created to demonstrate that it is possible to make a Captive \r\n        Portal with the ESP8266.<\/p>\r\n    <p class=\"style1\">\r\n        Created by Alberto Iglesias<\/p>\r\n\r\n<\/body>\r\n<\/html>\r\n";
      webServer.send(200, "text/html", metaRefreshStr);
    }
  });
 
  webServer.begin();
}
void loop() {
  dnsServer.processNextRequest();
  webServer.handleClient();
}
String getContentType(String filename){
  if(webServer.hasArg("download")) return "application/octet-stream";
  else if(filename.endsWith(".htm")) return "text/html";
  else if(filename.endsWith(".html")) return "text/html";
  else if(filename.endsWith(".css")) return "text/css";
  else if(filename.endsWith(".js")) return "application/javascript";
  else if(filename.endsWith(".png")) return "image/png";
  else if(filename.endsWith(".gif")) return "image/gif";
  else if(filename.endsWith(".jpg")) return "image/jpeg";
  else if(filename.endsWith(".ico")) return "image/x-icon";
  else if(filename.endsWith(".xml")) return "text/xml";
  else if(filename.endsWith(".pdf")) return "application/x-pdf";
  else if(filename.endsWith(".zip")) return "application/x-zip";
  else if(filename.endsWith(".gz")) return "application/x-gzip";
  return "text/plain";
}
//Given a file path, look for it in the SPIFFS file storage. Returns true if found, returns false if not found.
bool handleFileRead(String path){
  DBG_OUTPUT_PORT.println("handleFileRead: " + path);
  if(path.endsWith("/")) path += "index.html";
  String contentType = getContentType(path);
  String pathWithGz = path + ".gz";
  if(SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)){
    if(SPIFFS.exists(pathWithGz))
      path += ".gz";
    File file = SPIFFS.open(path, "r");
    size_t sent = webServer.streamFile(file, contentType);
    file.close();
    return true;
  }
  return false;
}
 
Upvote 0

Alberto Iglesias

Well-Known Member
Licensed User
Longtime User
The important part of this is this one:

B4X:
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <FS.h>
#define DBG_OUTPUT_PORT Serial
const byte DNS_PORT = 53;
const char *ssid = "B4X - Captive Portal";
IPAddress apIP(192, 168, 1, 1);
DNSServer dnsServer;
ESP8266WebServer webServer(80);

void setup() {
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP(ssid);
  dnsServer.start(DNS_PORT, "*", apIP);
  DBG_OUTPUT_PORT.begin(115200);
  DBG_OUTPUT_PORT.print("\n");
  DBG_OUTPUT_PORT.setDebugOutput(true);
  SPIFFS.begin();
  //redirect all traffic to index.html
  webServer.onNotFound([]() {
      const char *metaRefreshStr = "<!DOCTYPE html PUBLIC \"-\/\/W3C\/\/DTD XHTML 1.0 Transitional\/\/EN\" \"http:\/\/www.w3.org\/TR\/xhtml1\/DTD\/xhtml1-transitional.dtd\">\r\n<html xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\" >\r\n<head>\r\n    <title><\/title>\r\n    <style type=\"text\/css\">\r\n        .style1\r\n        {\r\n            font-family: Arial, Helvetica, sans-serif;\r\n            font-weight: bold;\r\n        }\r\n    <\/style>\r\n<\/head>\r\n<body>\r\n\r\n    <p class=\"style1\">\r\n        This page was created to demonstrate that it is possible to make a Captive \r\n        Portal with the ESP8266.<\/p>\r\n    <p class=\"style1\">\r\n        Created by Alberto Iglesias<\/p>\r\n\r\n<\/body>\r\n<\/html>\r\n";
      webServer.send(200, "text/html", metaRefreshStr);
  });
 
  webServer.begin();
}
void loop() {
  dnsServer.processNextRequest();
  webServer.handleClient();
}

@Erel, how difficult is put this on inline code or make some library?

Because I see some duplication on "loop" function when trying to compile
 
Upvote 0
Top