Implemented handling of WiFi settings

This commit is contained in:
Thomas Basler 2022-04-10 17:37:54 +02:00
parent 8b7f2a14b6
commit 94719be928
6 changed files with 215 additions and 2 deletions

View File

@ -5,9 +5,23 @@
#define CONFIG_FILENAME "/config.bin"
#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 {
uint32_t Cfg_Version;
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 {

31
include/WiFiSettings.h Normal file
View 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;

View File

@ -1,3 +1,16 @@
#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

View File

@ -1,4 +1,5 @@
#include "Configuration.h"
#include "defaults.h"
#include <LittleFS.h>
CONFIG_T config;
@ -8,6 +9,12 @@ void ConfigurationClass::init()
memset(&config, 0x0, sizeof(config));
config.Cfg_SaveCount = 0;
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()

144
src/WiFiSettings.cpp Normal file
View 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;

View File

@ -1,4 +1,5 @@
#include "Configuration.h"
#include "WiFiSettings.h"
#include "defaults.h"
#include <Arduino.h>
#include <LittleFS.h>
@ -39,9 +40,12 @@ void setup()
// Initialize WiFi
Serial.print(F("Initialize WiFi... "));
WiFiSettings.init();
Serial.println(F("done"));
WiFiSettings.applyConfig();
}
void loop()
{
// put your main code here, to run repeatedly:
WiFiSettings.loop();
}