Implemented handling of WiFi settings
This commit is contained in:
parent
8b7f2a14b6
commit
94719be928
@ -5,9 +5,23 @@
|
|||||||
#define CONFIG_FILENAME "/config.bin"
|
#define CONFIG_FILENAME "/config.bin"
|
||||||
#define CONFIG_VERSION 0x00010000 // 0.1.0
|
#define CONFIG_VERSION 0x00010000 // 0.1.0
|
||||||
|
|
||||||
|
#define WIFI_MAX_SSID_STRLEN 31
|
||||||
|
#define WIFI_MAX_PASSWORD_STRLEN 31
|
||||||
|
#define WIFI_MAX_HOSTNAME_STRLEN 31
|
||||||
|
|
||||||
struct CONFIG_T {
|
struct CONFIG_T {
|
||||||
uint32_t Cfg_Version;
|
uint32_t Cfg_Version;
|
||||||
uint Cfg_SaveCount;
|
uint Cfg_SaveCount;
|
||||||
|
|
||||||
|
char WiFi_Ssid[WIFI_MAX_SSID_STRLEN + 1];
|
||||||
|
char WiFi_Password[WIFI_MAX_PASSWORD_STRLEN + 1];
|
||||||
|
byte WiFi_Ip[4];
|
||||||
|
byte WiFi_Netmask[4];
|
||||||
|
byte WiFi_Gateway[4];
|
||||||
|
byte WiFi_Dns1[4];
|
||||||
|
byte WiFi_Dns2[4];
|
||||||
|
bool WiFi_Dhcp;
|
||||||
|
char WiFi_Hostname[WIFI_MAX_HOSTNAME_STRLEN + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConfigurationClass {
|
class ConfigurationClass {
|
||||||
|
|||||||
31
include/WiFiSettings.h
Normal file
31
include/WiFiSettings.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <DNSServer.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class WiFiSettingsClass {
|
||||||
|
public:
|
||||||
|
WiFiSettingsClass();
|
||||||
|
void init();
|
||||||
|
void loop();
|
||||||
|
void applyConfig();
|
||||||
|
void enableAdminMode();
|
||||||
|
String getApName();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setHostname();
|
||||||
|
void setStaticIp();
|
||||||
|
void setupMode();
|
||||||
|
bool adminEnabled = true;
|
||||||
|
bool forceDisconnection = false;
|
||||||
|
int adminTimeoutCounter = 0;
|
||||||
|
int connectTimeoutTimer = 0;
|
||||||
|
int connectRedoTimer = 0;
|
||||||
|
unsigned long lastTimerCall = 0;
|
||||||
|
const byte DNS_PORT = 53;
|
||||||
|
IPAddress apIp;
|
||||||
|
IPAddress apNetmask;
|
||||||
|
std::unique_ptr<DNSServer> dnsServer;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern WiFiSettingsClass WiFiSettings;
|
||||||
@ -1,3 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define SERIAL_BAUDRATE 115200
|
#define SERIAL_BAUDRATE 115200
|
||||||
|
|
||||||
|
#define APP_HOSTNAME "OpenDTU-%06X"
|
||||||
|
|
||||||
|
#define ACCESS_POINT_NAME "OpenDTU-"
|
||||||
|
#define ACCESS_POINT_PASSWORD "openDTU"
|
||||||
|
|
||||||
|
#define ADMIN_TIMEOUT 180
|
||||||
|
#define WIFI_RECONNECT_TIMEOUT 15
|
||||||
|
#define WIFI_RECONNECT_REDO_TIMEOUT 600
|
||||||
|
|
||||||
|
#define WIFI_SSID ""
|
||||||
|
#define WIFI_PASSWORD ""
|
||||||
|
#define WIFI_DHCP true
|
||||||
@ -1,4 +1,5 @@
|
|||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
|
#include "defaults.h"
|
||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
|
|
||||||
CONFIG_T config;
|
CONFIG_T config;
|
||||||
@ -8,6 +9,12 @@ void ConfigurationClass::init()
|
|||||||
memset(&config, 0x0, sizeof(config));
|
memset(&config, 0x0, sizeof(config));
|
||||||
config.Cfg_SaveCount = 0;
|
config.Cfg_SaveCount = 0;
|
||||||
config.Cfg_Version = CONFIG_VERSION;
|
config.Cfg_Version = CONFIG_VERSION;
|
||||||
|
|
||||||
|
// WiFi Settings
|
||||||
|
strlcpy(config.WiFi_Ssid, WIFI_SSID, sizeof(config.WiFi_Ssid));
|
||||||
|
strlcpy(config.WiFi_Password, WIFI_PASSWORD, sizeof(config.WiFi_Password));
|
||||||
|
config.WiFi_Dhcp = WIFI_DHCP;
|
||||||
|
strlcpy(config.WiFi_Hostname, APP_HOSTNAME, sizeof(config.WiFi_Hostname));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigurationClass::write()
|
bool ConfigurationClass::write()
|
||||||
|
|||||||
144
src/WiFiSettings.cpp
Normal file
144
src/WiFiSettings.cpp
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
#include "WiFiSettings.h"
|
||||||
|
#include "Configuration.h"
|
||||||
|
#include "defaults.h"
|
||||||
|
#include <WiFi.h>
|
||||||
|
|
||||||
|
WiFiSettingsClass::WiFiSettingsClass()
|
||||||
|
: apIp(172, 217, 28, 1)
|
||||||
|
, apNetmask(255, 255, 255, 0)
|
||||||
|
{
|
||||||
|
dnsServer.reset(new DNSServer());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiSettingsClass::init()
|
||||||
|
{
|
||||||
|
setupMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiSettingsClass::setupMode()
|
||||||
|
{
|
||||||
|
if (adminEnabled) {
|
||||||
|
WiFi.mode(WIFI_AP_STA);
|
||||||
|
String ssidString = getApName();
|
||||||
|
WiFi.softAPConfig(apIp, apIp, apNetmask);
|
||||||
|
WiFi.softAP((const char*)ssidString.c_str(), ACCESS_POINT_PASSWORD);
|
||||||
|
dnsServer->setErrorReplyCode(DNSReplyCode::NoError);
|
||||||
|
dnsServer->start(DNS_PORT, "*", WiFi.softAPIP());
|
||||||
|
} else {
|
||||||
|
dnsServer->stop();
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiSettingsClass::enableAdminMode()
|
||||||
|
{
|
||||||
|
adminEnabled = true;
|
||||||
|
adminTimeoutCounter = 0;
|
||||||
|
setupMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
String WiFiSettingsClass::getApName()
|
||||||
|
{
|
||||||
|
uint32_t chipId = 0;
|
||||||
|
for (int i = 0; i < 17; i += 8) {
|
||||||
|
chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
|
||||||
|
}
|
||||||
|
return String(ACCESS_POINT_NAME + String(chipId));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiSettingsClass::loop()
|
||||||
|
{
|
||||||
|
if (millis() - lastTimerCall > 1000) {
|
||||||
|
adminTimeoutCounter++;
|
||||||
|
connectTimeoutTimer++;
|
||||||
|
connectRedoTimer++;
|
||||||
|
lastTimerCall = millis();
|
||||||
|
}
|
||||||
|
if (adminEnabled) {
|
||||||
|
// Don't disable the admin mode when WiFi is not available
|
||||||
|
if (WiFi.status() != WL_CONNECTED) {
|
||||||
|
adminTimeoutCounter = 0;
|
||||||
|
}
|
||||||
|
// If WiFi is connected to AP for more than ADMIN_TIMEOUT
|
||||||
|
// seconds, disable the internal Access Point
|
||||||
|
if (adminTimeoutCounter > ADMIN_TIMEOUT) {
|
||||||
|
adminEnabled = false;
|
||||||
|
Serial.println(F("Admin mode disabled"));
|
||||||
|
setupMode();
|
||||||
|
}
|
||||||
|
// It's nearly not possible to use the internal AP if the
|
||||||
|
// WiFi is searching for an AP. So disable searching afer
|
||||||
|
// WIFI_RECONNECT_TIMEOUT and repeat after WIFI_RECONNECT_REDO_TIMEOUT
|
||||||
|
if (WiFi.status() == WL_CONNECTED) {
|
||||||
|
connectTimeoutTimer = 0;
|
||||||
|
connectRedoTimer = 0;
|
||||||
|
} else {
|
||||||
|
if (connectTimeoutTimer > WIFI_RECONNECT_TIMEOUT && !forceDisconnection) {
|
||||||
|
Serial.print(F("Disable search for AP... "));
|
||||||
|
WiFi.mode(WIFI_AP);
|
||||||
|
Serial.println(F("done"));
|
||||||
|
connectRedoTimer = 0;
|
||||||
|
forceDisconnection = true;
|
||||||
|
}
|
||||||
|
if (connectRedoTimer > WIFI_RECONNECT_REDO_TIMEOUT && forceDisconnection) {
|
||||||
|
Serial.print(F("Enable search for AP... "));
|
||||||
|
WiFi.mode(WIFI_AP_STA);
|
||||||
|
Serial.println(F("done"));
|
||||||
|
applyConfig();
|
||||||
|
connectTimeoutTimer = 0;
|
||||||
|
forceDisconnection = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dnsServer->processNextRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiSettingsClass::applyConfig()
|
||||||
|
{
|
||||||
|
setHostname();
|
||||||
|
if (!strcmp(Configuration.get().WiFi_Ssid, "")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Serial.print(F("Configuring WiFi STA using "));
|
||||||
|
if (strcmp(WiFi.SSID().c_str(), Configuration.get().WiFi_Ssid) || strcmp(WiFi.psk().c_str(), Configuration.get().WiFi_Password)) {
|
||||||
|
Serial.print(F("new credentials... "));
|
||||||
|
WiFi.begin(
|
||||||
|
Configuration.get().WiFi_Ssid,
|
||||||
|
Configuration.get().WiFi_Password);
|
||||||
|
} else {
|
||||||
|
Serial.print(F("existing credentials... "));
|
||||||
|
WiFi.begin();
|
||||||
|
}
|
||||||
|
Serial.println("done");
|
||||||
|
setStaticIp();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiSettingsClass::setHostname()
|
||||||
|
{
|
||||||
|
Serial.print(F("Setting Hostname... "));
|
||||||
|
if (strcmp(Configuration.get().WiFi_Hostname, "")) {
|
||||||
|
if (WiFi.hostname(Configuration.get().WiFi_Hostname)) {
|
||||||
|
Serial.println(F("done"));
|
||||||
|
} else {
|
||||||
|
Serial.println(F("failed"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.println(F("failed (Hostname empty)"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiFiSettingsClass::setStaticIp()
|
||||||
|
{
|
||||||
|
if (!Configuration.get().WiFi_Dhcp) {
|
||||||
|
Serial.print(F("Configuring WiFi STA static IP... "));
|
||||||
|
WiFi.config(
|
||||||
|
IPAddress(Configuration.get().WiFi_Ip),
|
||||||
|
IPAddress(Configuration.get().WiFi_Gateway),
|
||||||
|
IPAddress(Configuration.get().WiFi_Netmask),
|
||||||
|
IPAddress(Configuration.get().WiFi_Dns1),
|
||||||
|
IPAddress(Configuration.get().WiFi_Dns2));
|
||||||
|
Serial.println(F("done"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WiFiSettingsClass WiFiSettings;
|
||||||
@ -1,4 +1,5 @@
|
|||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
|
#include "WiFiSettings.h"
|
||||||
#include "defaults.h"
|
#include "defaults.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
@ -39,9 +40,12 @@ void setup()
|
|||||||
|
|
||||||
// Initialize WiFi
|
// Initialize WiFi
|
||||||
Serial.print(F("Initialize WiFi... "));
|
Serial.print(F("Initialize WiFi... "));
|
||||||
|
WiFiSettings.init();
|
||||||
|
Serial.println(F("done"));
|
||||||
|
WiFiSettings.applyConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
// put your main code here, to run repeatedly:
|
WiFiSettings.loop();
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user