Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.

Initial implementation of WiFiManager #226

Merged
merged 1 commit into from
Dec 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/Portal.h

This file was deleted.

3 changes: 3 additions & 0 deletions src/Thing.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "thing/Transcriber.h"
#include "thing/Portal.h"
#include "thing/WiFiManager.h"
1 change: 0 additions & 1 deletion src/Transcriber.h

This file was deleted.

4 changes: 3 additions & 1 deletion src/thing/Portal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Portal::Portal(const Config& config)
debug_([](const char*){}) {}

void Portal::SetDebugHandler(std::function<void(const char* message)> handler) {
debug_ = handler;
debug_ = std::move(handler);
}

void Portal::Start() {
Expand Down Expand Up @@ -150,6 +150,8 @@ void Portal::Start() {
entry["ssid"] = WiFi.SSID(i);
entry["rssi"] = WiFi.RSSI(i);
}
// Free station info from memory.
WiFi.scanDelete();

String buffer;
data.printTo(buffer);
Expand Down
69 changes: 69 additions & 0 deletions src/thing/WiFiManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include "thing/WiFiManager.h"

#include <ESP8266WiFi.h>
#include <DNSServer.h>


namespace thing {
namespace {

const short kDnsPort = 53;

} // namespace

WiFiManager::WiFiManager() : debug_([](const char*){}) {}

bool WiFiManager::StartAP() {
// Use arduino string, casting an int to std::string with arduino C++ support
// isn't easy.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::to_string didn't work?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, not defined for some reason. There are other std:: things that arduino c++ doesn't support as well.

String ssid("FireThing-");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be a constant format string?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best I can tell there is no easy printf support in arduino. We can use c printf but you need to allocate a buffer and do the manipulations there which is what I was avoiding by just using arduino's string and concatenation.

ssid += ESP.getChipId();

WiFi.mode(WIFI_AP_STA);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use the mixed mode where we can be both client and station?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is this one. AP is access point and STA is wifi's wierd name for a client.

if (!WiFi.softAP(ssid.c_str())) {
Copy link
Contributor

@proppy proppy Nov 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

snould we retry if that fail?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The caller of this is free to retry on failure. I don't actually know what would cause this to fail.

return false;
}

debug_((String("WiFi AP : ") + ssid).c_str());
debug_((String("Wifi AP IP : ") + WiFi.softAPIP().toString()).c_str());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you explore mdns support so that you don't have to rely on the IP?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The IP is actually always the same, it is hard coded to 192.168.4.1 . mdns would be great for when we are in station mode though, that way we can be configured all the time without having to access our captive portal. I haven't looked into it though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be great if we can have the same mdns name for STA and AP mode:

  • the user connect to Firethings AP
  • the captive portal redirect the user to firebase.local
  • the user configure credentials and firethings connect to the wifi network
  • the user reconnect to the home router AP
  • the user refresh firebase.local and still access the same configuration UI.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that does sound pretty compelling. I spawned #233 to explore this, don't see any point blocking this PR on it though as this will be the basis for that work.


dns_.reset(new DNSServer());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is that also doing dhcp or just dns? if the late could we return 8.8.8.8 instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how you do a captive portal. You become the dns server and just return your own ip address for every lookup attempt. This is how WiFiManager (the arduino library) was doing it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to bring down the dns once the device is connected to wifi? Will it only get request from the WiFi AP network?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could leave it running indefinitely without any issues.
What DNS servers your computer uses is part of the settings that DHCP provides. So if you are a client of the esp's DHCP server you will get this as your dns server (I am not certain how this is specified actually as we never talk directly to the esp's dhcp server but it works). But if you are a client of another DHCP server, like if you are on GoogleGuest, than you will get their dns servers (probably 8.8.8.8, Google's dns server).

dns_->start(kDnsPort, "*", WiFi.softAPIP());
dns_->setTTL(30);

ap_up_ = true;
return true;
}

bool WiFiManager::StopAP() {
if (!WiFi.softAPdisconnect()) {
return false;
}
dns_->stop();
dns_.reset(nullptr);

ap_up_ = false;
return true;
}

void WiFiManager::Loop() {
if (dns_) {
dns_->processNextRequest();
}
}

bool WiFiManager::Connect(const std::string& ssid, const std::string& auth) {
auto status = WiFi.begin(ssid.c_str(), auth.c_str());

return status != WL_CONNECT_FAILED;
}

bool WiFiManager::connected() const {
return WiFi.status() == WL_CONNECTED;
}

void WiFiManager::SetDebugHandler(std::function<void(const char* message)> handler) {
debug_ = std::move(handler);
}

};
31 changes: 31 additions & 0 deletions src/thing/WiFiManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef THING_WIFI_MANAGER_H
#define THING_WIFI_MANAGER_H

#include <ESP8266WiFi.h>
#include <DNSServer.h>

namespace thing {

class WiFiManager {
public:
WiFiManager();

bool StartAP();
bool StopAP();
bool Connect(const std::string& ssid, const std::string& auth);

void Loop();

bool connected() const;
bool ap_up() const { return ap_up_; }

void SetDebugHandler(std::function<void(const char* message)> handler);
private:
bool ap_up_ = false;
std::unique_ptr<DNSServer> dns_;
std::function<void(const char* message)> debug_;
};

};

#endif // THING_WIFI_MANAGER_H