mirror of
https://github.com/lumapu/ahoy.git
synced 2025-04-30 02:36:20 +02:00
ethernet and wifi are working for ESP32
This commit is contained in:
parent
a44a5833ca
commit
89f7b4f1c6
16 changed files with 239 additions and 984 deletions
32
src/app.cpp
32
src/app.cpp
|
@ -53,17 +53,16 @@ void app::setup() {
|
||||||
mCmtRadio.setup(&mConfig->serial.debug, &mConfig->serial.privacyLog, &mConfig->serial.printWholeTrace, mConfig->cmt.pinSclk, mConfig->cmt.pinSdio, mConfig->cmt.pinCsb, mConfig->cmt.pinFcsb, mConfig->sys.region);
|
mCmtRadio.setup(&mConfig->serial.debug, &mConfig->serial.privacyLog, &mConfig->serial.printWholeTrace, mConfig->cmt.pinSclk, mConfig->cmt.pinSdio, mConfig->cmt.pinCsb, mConfig->cmt.pinFcsb, mConfig->sys.region);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ETHERNET
|
#ifdef ETHERNET
|
||||||
delay(1000);
|
delay(1000);
|
||||||
mEth.setup(mConfig, &mTimestamp, [this](bool gotIp) { this->onNetwork(gotIp); }, [this](bool gotTime) { this->onNtpUpdate(gotTime); });
|
mNetwork = (AhoyNetwork*) new AhoyEthernet();
|
||||||
|
#else
|
||||||
|
mNetwork = (AhoyNetwork*) new AhoyWifi();
|
||||||
#endif // ETHERNET
|
#endif // ETHERNET
|
||||||
|
mNetwork->setup(mConfig, &mTimestamp, [this](bool gotIp) { this->onNetwork(gotIp); }, [this](bool gotTime) { this->onNtpUpdate(gotTime); });
|
||||||
#if !defined(ETHERNET)
|
mNetwork->begin();
|
||||||
mWifi.setup(mConfig, &mTimestamp, [this](bool gotIp) { this->onNetwork(gotIp); }, [this](bool gotTime) { this->onNtpUpdate(gotTime); });
|
everySec(std::bind(&AhoyNetwork::tickNetworkLoop, mNetwork), "net");
|
||||||
#if !defined(AP_ONLY)
|
|
||||||
everySec(std::bind(&ahoywifi::tickWifiLoop, &mWifi), "wifiL");
|
|
||||||
#endif
|
|
||||||
#endif /* defined(ETHERNET) */
|
|
||||||
|
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
|
|
||||||
|
@ -89,7 +88,7 @@ void app::setup() {
|
||||||
#if defined(ENABLE_MQTT)
|
#if defined(ENABLE_MQTT)
|
||||||
mMqttEnabled = (mConfig->mqtt.broker[0] > 0);
|
mMqttEnabled = (mConfig->mqtt.broker[0] > 0);
|
||||||
if (mMqttEnabled) {
|
if (mMqttEnabled) {
|
||||||
mMqtt.setup(&mConfig->mqtt, mConfig->sys.deviceName, mVersion, &mSys, &mTimestamp, &mUptime);
|
mMqtt.setup(this, &mConfig->mqtt, mConfig->sys.deviceName, mVersion, &mSys, &mTimestamp, &mUptime);
|
||||||
mMqtt.setSubscriptionCb(std::bind(&app::mqttSubRxCb, this, std::placeholders::_1));
|
mMqtt.setSubscriptionCb(std::bind(&app::mqttSubRxCb, this, std::placeholders::_1));
|
||||||
mCommunication.addAlarmListener([this](Inverter<> *iv) { mMqtt.alarmEvent(iv); });
|
mCommunication.addAlarmListener([this](Inverter<> *iv) { mMqtt.alarmEvent(iv); });
|
||||||
}
|
}
|
||||||
|
@ -171,12 +170,6 @@ void app::onNetwork(bool gotIp) {
|
||||||
mMqttReconnect = true;
|
mMqttReconnect = true;
|
||||||
mSunrise = 0; // needs to be set to 0, to reinstall sunrise and ivComm tickers!
|
mSunrise = 0; // needs to be set to 0, to reinstall sunrise and ivComm tickers!
|
||||||
once(std::bind(&app::tickNtpUpdate, this), 2, "ntp2");
|
once(std::bind(&app::tickNtpUpdate, this), 2, "ntp2");
|
||||||
#if !defined(ETHERNET)
|
|
||||||
if (WIFI_AP == WiFi.getMode()) {
|
|
||||||
mMqttEnabled = false;
|
|
||||||
}
|
|
||||||
everySec(std::bind(&ahoywifi::tickWifiLoop, &mWifi), "wifiL");
|
|
||||||
#endif /* !defined(ETHERNET) */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -248,17 +241,10 @@ void app::updateNtp(void) {
|
||||||
void app::tickNtpUpdate(void) {
|
void app::tickNtpUpdate(void) {
|
||||||
uint32_t nxtTrig = 5; // default: check again in 5 sec
|
uint32_t nxtTrig = 5; // default: check again in 5 sec
|
||||||
|
|
||||||
#if defined(ETHERNET)
|
|
||||||
if (!mNtpReceived)
|
if (!mNtpReceived)
|
||||||
mEth.updateNtpTime();
|
mNetwork->updateNtpTime();
|
||||||
else
|
else
|
||||||
mNtpReceived = false;
|
mNtpReceived = false;
|
||||||
#else
|
|
||||||
if (!mNtpReceived)
|
|
||||||
mWifi.updateNtpTime();
|
|
||||||
else
|
|
||||||
mNtpReceived = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
updateNtp();
|
updateNtp();
|
||||||
nxtTrig = mConfig->ntp.interval * 60; // check again in 12h
|
nxtTrig = mConfig->ntp.interval * 60; // check again in 12h
|
||||||
|
|
39
src/app.h
39
src/app.h
|
@ -37,9 +37,9 @@
|
||||||
#include "web/web.h"
|
#include "web/web.h"
|
||||||
#include "hm/Communication.h"
|
#include "hm/Communication.h"
|
||||||
#if defined(ETHERNET)
|
#if defined(ETHERNET)
|
||||||
#include "eth/ahoyeth.h"
|
#include "network/AhoyEthernet.h"
|
||||||
#else /* defined(ETHERNET) */
|
#else /* defined(ETHERNET) */
|
||||||
#include "wifi/ahoywifi.h"
|
#include "network/AhoyWifiEsp32.h"
|
||||||
#include "utils/improv.h"
|
#include "utils/improv.h"
|
||||||
#endif /* defined(ETHERNET) */
|
#endif /* defined(ETHERNET) */
|
||||||
|
|
||||||
|
@ -164,31 +164,30 @@ class app : public IApp, public ah::Scheduler {
|
||||||
|
|
||||||
#if !defined(ETHERNET)
|
#if !defined(ETHERNET)
|
||||||
void scanAvailNetworks() override {
|
void scanAvailNetworks() override {
|
||||||
mWifi.scanAvailNetworks();
|
mNetwork->scanAvailNetworks();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getAvailNetworks(JsonObject obj) override {
|
bool getAvailNetworks(JsonObject obj) override {
|
||||||
return mWifi.getAvailNetworks(obj);
|
return mNetwork->getAvailNetworks(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupStation(void) override {
|
void setupStation(void) override {
|
||||||
mWifi.setupStation();
|
mNetwork->begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setStopApAllowedMode(bool allowed) override {
|
/*void setStopApAllowedMode(bool allowed) override {
|
||||||
mWifi.setStopApAllowedMode(allowed);
|
mWifi.setStopApAllowedMode(allowed);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
String getStationIp(void) override {
|
|
||||||
return mWifi.getStationIp();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getWasInCh12to14(void) const override {
|
bool getWasInCh12to14(void) const override {
|
||||||
return mWifi.getWasInCh12to14();
|
return false; // @todo mWifi.getWasInCh12to14();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !defined(ETHERNET) */
|
#endif /* !defined(ETHERNET) */
|
||||||
|
|
||||||
|
String getIp(void) override {
|
||||||
|
return mNetwork->getIp();
|
||||||
|
}
|
||||||
|
|
||||||
void setRebootFlag() override {
|
void setRebootFlag() override {
|
||||||
once(std::bind(&app::tickReboot, this), 3, "rboot");
|
once(std::bind(&app::tickReboot, this), 3, "rboot");
|
||||||
}
|
}
|
||||||
|
@ -295,13 +294,7 @@ class app : public IApp, public ah::Scheduler {
|
||||||
DPRINT(DBG_DEBUG, F("setTimestamp: "));
|
DPRINT(DBG_DEBUG, F("setTimestamp: "));
|
||||||
DBGPRINTLN(String(newTime));
|
DBGPRINTLN(String(newTime));
|
||||||
if(0 == newTime)
|
if(0 == newTime)
|
||||||
{
|
mNetwork->updateNtpTime();
|
||||||
#if defined(ETHERNET)
|
|
||||||
mEth.updateNtpTime();
|
|
||||||
#else /* defined(ETHERNET) */
|
|
||||||
mWifi.updateNtpTime();
|
|
||||||
#endif /* defined(ETHERNET) */
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
Scheduler::setTimestamp(newTime);
|
Scheduler::setTimestamp(newTime);
|
||||||
}
|
}
|
||||||
|
@ -414,11 +407,7 @@ class app : public IApp, public ah::Scheduler {
|
||||||
|
|
||||||
bool mShowRebootRequest = false;
|
bool mShowRebootRequest = false;
|
||||||
|
|
||||||
#if defined(ETHERNET)
|
AhoyNetwork *mNetwork;
|
||||||
ahoyeth mEth;
|
|
||||||
#else /* defined(ETHERNET) */
|
|
||||||
ahoywifi mWifi;
|
|
||||||
#endif /* defined(ETHERNET) */
|
|
||||||
WebType mWeb;
|
WebType mWeb;
|
||||||
RestApiType mApi;
|
RestApiType mApi;
|
||||||
Protection *mProtection = nullptr;
|
Protection *mProtection = nullptr;
|
||||||
|
|
|
@ -29,10 +29,10 @@ class IApp {
|
||||||
virtual void scanAvailNetworks() = 0;
|
virtual void scanAvailNetworks() = 0;
|
||||||
virtual bool getAvailNetworks(JsonObject obj) = 0;
|
virtual bool getAvailNetworks(JsonObject obj) = 0;
|
||||||
virtual void setupStation(void) = 0;
|
virtual void setupStation(void) = 0;
|
||||||
virtual void setStopApAllowedMode(bool allowed) = 0;
|
//virtual void setStopApAllowedMode(bool allowed) = 0;
|
||||||
virtual String getStationIp(void) = 0;
|
|
||||||
virtual bool getWasInCh12to14(void) const = 0;
|
virtual bool getWasInCh12to14(void) const = 0;
|
||||||
#endif /* defined(ETHERNET) */
|
#endif /* defined(ETHERNET) */
|
||||||
|
virtual String getIp(void) = 0;
|
||||||
|
|
||||||
virtual uint32_t getUptime() = 0;
|
virtual uint32_t getUptime() = 0;
|
||||||
virtual uint32_t getTimestamp() = 0;
|
virtual uint32_t getTimestamp() = 0;
|
||||||
|
|
|
@ -91,10 +91,11 @@ typedef struct {
|
||||||
char stationSsid[SSID_LEN];
|
char stationSsid[SSID_LEN];
|
||||||
char stationPwd[PWD_LEN];
|
char stationPwd[PWD_LEN];
|
||||||
bool isHidden;
|
bool isHidden;
|
||||||
|
#else
|
||||||
|
cfgEth_t eth;
|
||||||
#endif /* !defined(ETHERNET) */
|
#endif /* !defined(ETHERNET) */
|
||||||
|
|
||||||
cfgIp_t ip;
|
cfgIp_t ip;
|
||||||
cfgEth_t eth;
|
|
||||||
} cfgSys_t;
|
} cfgSys_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -1,179 +0,0 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// 2023 Ahoy, https://www.mikrocontroller.net/topic/525778
|
|
||||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#if defined(ETHERNET)
|
|
||||||
|
|
||||||
#if defined(ESP32) && defined(F)
|
|
||||||
#undef F
|
|
||||||
#define F(sl) (sl)
|
|
||||||
#endif
|
|
||||||
#include "ahoyeth.h"
|
|
||||||
#include <ESPmDNS.h>
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
ahoyeth::ahoyeth()
|
|
||||||
{
|
|
||||||
// WiFi.onEvent(ESP32_W5500_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void ahoyeth::setup(settings_t *config, uint32_t *utcTimestamp, OnNetworkCB onNetworkCB, OnTimeCB onTimeCB) {
|
|
||||||
mConfig = config;
|
|
||||||
mUtcTimestamp = utcTimestamp;
|
|
||||||
mOnNetworkCB = onNetworkCB;
|
|
||||||
mOnTimeCB = onTimeCB;
|
|
||||||
mEthConnected = false;
|
|
||||||
|
|
||||||
Serial.flush();
|
|
||||||
WiFi.onEvent([this](WiFiEvent_t event, arduino_event_info_t info) -> void { this->onEthernetEvent(event, info); });
|
|
||||||
|
|
||||||
Serial.flush();
|
|
||||||
mEthSpi.begin(config->sys.eth.pinMiso, config->sys.eth.pinMosi, config->sys.eth.pinSclk, config->sys.eth.pinCs, config->sys.eth.pinIrq, config->sys.eth.pinRst);
|
|
||||||
|
|
||||||
if(mConfig->sys.ip.ip[0] != 0) {
|
|
||||||
IPAddress ip(mConfig->sys.ip.ip);
|
|
||||||
IPAddress mask(mConfig->sys.ip.mask);
|
|
||||||
IPAddress dns1(mConfig->sys.ip.dns1);
|
|
||||||
IPAddress dns2(mConfig->sys.ip.dns2);
|
|
||||||
IPAddress gateway(mConfig->sys.ip.gateway);
|
|
||||||
if(!ETH.config(ip, gateway, mask, dns1, dns2))
|
|
||||||
DPRINTLN(DBG_ERROR, F("failed to set static IP!"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
bool ahoyeth::updateNtpTime(void) {
|
|
||||||
if (!ETH.localIP())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
DPRINTLN(DBG_DEBUG, F("updateNtpTime: checking udp \"connection\"...")); Serial.flush();
|
|
||||||
if (!mUdp.connected()) {
|
|
||||||
DPRINTLN(DBG_DEBUG, F("updateNtpTime: About to (re)connect...")); Serial.flush();
|
|
||||||
IPAddress timeServer;
|
|
||||||
if (!WiFi.hostByName(mConfig->ntp.addr, timeServer))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!mUdp.connect(timeServer, mConfig->ntp.port))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
DPRINTLN(DBG_DEBUG, F("updateNtpTime: Connected...")); Serial.flush();
|
|
||||||
mUdp.onPacket([this](AsyncUDPPacket packet) {
|
|
||||||
DPRINTLN(DBG_DEBUG, F("updateNtpTime: about to handle ntp packet...")); Serial.flush();
|
|
||||||
this->handleNTPPacket(packet);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINTLN(DBG_DEBUG, F("updateNtpTime: prepare packet...")); Serial.flush();
|
|
||||||
|
|
||||||
// set all bytes in the buffer to 0
|
|
||||||
memset(mUdpPacketBuffer, 0, NTP_PACKET_SIZE);
|
|
||||||
// Initialize values needed to form NTP request
|
|
||||||
// (see URL above for details on the packets)
|
|
||||||
|
|
||||||
mUdpPacketBuffer[0] = 0b11100011; // LI, Version, Mode
|
|
||||||
mUdpPacketBuffer[1] = 0; // Stratum, or type of clock
|
|
||||||
mUdpPacketBuffer[2] = 6; // Polling Interval
|
|
||||||
mUdpPacketBuffer[3] = 0xEC; // Peer Clock Precision
|
|
||||||
|
|
||||||
// 8 bytes of zero for Root Delay & Root Dispersion
|
|
||||||
mUdpPacketBuffer[12] = 49;
|
|
||||||
mUdpPacketBuffer[13] = 0x4E;
|
|
||||||
mUdpPacketBuffer[14] = 49;
|
|
||||||
mUdpPacketBuffer[15] = 52;
|
|
||||||
|
|
||||||
//Send unicast
|
|
||||||
DPRINTLN(DBG_DEBUG, F("updateNtpTime: send packet...")); Serial.flush();
|
|
||||||
mUdp.write(mUdpPacketBuffer, sizeof(mUdpPacketBuffer));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void ahoyeth::handleNTPPacket(AsyncUDPPacket packet) {
|
|
||||||
char buf[80];
|
|
||||||
|
|
||||||
memcpy(buf, packet.data(), sizeof(buf));
|
|
||||||
|
|
||||||
unsigned long highWord = word(buf[40], buf[41]);
|
|
||||||
unsigned long lowWord = word(buf[42], buf[43]);
|
|
||||||
|
|
||||||
// combine the four bytes (two words) into a long integer
|
|
||||||
// this is NTP time (seconds since Jan 1 1900):
|
|
||||||
unsigned long secsSince1900 = highWord << 16 | lowWord;
|
|
||||||
|
|
||||||
*mUtcTimestamp = secsSince1900 - 2208988800UL; // UTC time
|
|
||||||
DPRINTLN(DBG_INFO, "[NTP]: " + ah::getDateTimeStr(*mUtcTimestamp) + " UTC");
|
|
||||||
mOnTimeCB(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void ahoyeth::welcome(String ip, String mode) {
|
|
||||||
DBGPRINTLN(F("\n\n--------------------------------"));
|
|
||||||
DBGPRINTLN(F("Welcome to AHOY!"));
|
|
||||||
DBGPRINT(F("\npoint your browser to http://"));
|
|
||||||
DBGPRINT(ip);
|
|
||||||
DBGPRINTLN(mode);
|
|
||||||
DBGPRINTLN(F("to configure your device"));
|
|
||||||
DBGPRINTLN(F("--------------------------------\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ahoyeth::onEthernetEvent(WiFiEvent_t event, arduino_event_info_t info) {
|
|
||||||
DPRINTLN(DBG_VERBOSE, F("[ETH]: Got event..."));
|
|
||||||
switch (event) {
|
|
||||||
case ARDUINO_EVENT_ETH_START:
|
|
||||||
DPRINTLN(DBG_VERBOSE, F("ETH Started"));
|
|
||||||
|
|
||||||
if(String(mConfig->sys.deviceName) != "")
|
|
||||||
ETH.setHostname(mConfig->sys.deviceName);
|
|
||||||
else
|
|
||||||
ETH.setHostname(F("ESP32_W5500"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARDUINO_EVENT_ETH_CONNECTED:
|
|
||||||
DPRINTLN(DBG_VERBOSE, F("ETH Connected"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARDUINO_EVENT_ETH_GOT_IP:
|
|
||||||
if (!mEthConnected) {
|
|
||||||
/*DPRINT(DBG_INFO, F("ETH MAC: "));
|
|
||||||
DBGPRINT(mEthSpi.macAddress());*/
|
|
||||||
welcome(ETH.localIP().toString(), F(" (Station)"));
|
|
||||||
|
|
||||||
mEthConnected = true;
|
|
||||||
mOnNetworkCB(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!MDNS.begin(mConfig->sys.deviceName)) {
|
|
||||||
DPRINTLN(DBG_ERROR, F("Error setting up MDNS responder!"));
|
|
||||||
} else {
|
|
||||||
DBGPRINT(F("mDNS established: "));
|
|
||||||
DBGPRINT(mConfig->sys.deviceName);
|
|
||||||
DBGPRINTLN(F(".local"));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARDUINO_EVENT_ETH_DISCONNECTED:
|
|
||||||
DPRINTLN(DBG_INFO, F("ETH Disconnected"));
|
|
||||||
mEthConnected = false;
|
|
||||||
mUdp.close();
|
|
||||||
mOnNetworkCB(false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARDUINO_EVENT_ETH_STOP:
|
|
||||||
DPRINTLN(DBG_INFO, F("ETH Stopped"));
|
|
||||||
mEthConnected = false;
|
|
||||||
mUdp.close();
|
|
||||||
mOnNetworkCB(false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* defined(ETHERNET) */
|
|
|
@ -1,65 +0,0 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// 2024 Ahoy, https://github.com/lumpapu/ahoy
|
|
||||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#if defined(ETHERNET)
|
|
||||||
#ifndef __AHOYETH_H__
|
|
||||||
#define __AHOYETH_H__
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include "../utils/dbg.h"
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <AsyncUDP.h>
|
|
||||||
#include <DNSServer.h>
|
|
||||||
|
|
||||||
#include "ethSpi.h"
|
|
||||||
#include <ETH.h>
|
|
||||||
#include "../utils/dbg.h"
|
|
||||||
#include "../config/config.h"
|
|
||||||
#include "../config/settings.h"
|
|
||||||
|
|
||||||
|
|
||||||
class app;
|
|
||||||
|
|
||||||
#define NTP_PACKET_SIZE 48
|
|
||||||
|
|
||||||
class ahoyeth {
|
|
||||||
public: /* types */
|
|
||||||
typedef std::function<void(bool)> OnNetworkCB;
|
|
||||||
typedef std::function<void(bool)> OnTimeCB;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ahoyeth();
|
|
||||||
|
|
||||||
void setup(settings_t *config, uint32_t *utcTimestamp, OnNetworkCB onNetworkCB, OnTimeCB onTimeCB);
|
|
||||||
bool updateNtpTime(void);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void setupEthernet();
|
|
||||||
|
|
||||||
void handleNTPPacket(AsyncUDPPacket packet);
|
|
||||||
|
|
||||||
void welcome(String ip, String mode);
|
|
||||||
|
|
||||||
void onEthernetEvent(WiFiEvent_t event, arduino_event_info_t info);
|
|
||||||
|
|
||||||
private:
|
|
||||||
//#if defined(CONFIG_IDF_TARGET_ESP32S3)
|
|
||||||
EthSpi mEthSpi;
|
|
||||||
//#endif
|
|
||||||
settings_t *mConfig = nullptr;
|
|
||||||
|
|
||||||
uint32_t *mUtcTimestamp;
|
|
||||||
AsyncUDP mUdp; // for time server
|
|
||||||
byte mUdpPacketBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
|
|
||||||
|
|
||||||
OnNetworkCB mOnNetworkCB;
|
|
||||||
OnTimeCB mOnTimeCB;
|
|
||||||
bool mEthConnected;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*__AHOYETH_H__*/
|
|
||||||
#endif /* defined(ETHERNET) */
|
|
|
@ -6,77 +6,64 @@
|
||||||
#ifndef __AHOY_ETHERNET_H__
|
#ifndef __AHOY_ETHERNET_H__
|
||||||
#define __AHOY_ETHERNET_H__
|
#define __AHOY_ETHERNET_H__
|
||||||
|
|
||||||
|
#if defined(ETHERNET)
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <AsyncUDP.h>
|
#include <AsyncUDP.h>
|
||||||
#include <ETH.h>
|
#include <ETH.h>
|
||||||
#include "AhoyEthernetSpi.h"
|
#include "AhoyEthernetSpi.h"
|
||||||
#include "AhoyEthernet.h"
|
#include "AhoyNetwork.h"
|
||||||
|
|
||||||
class AhoyEthernet : public AhoyNetwork {
|
class AhoyEthernet : public AhoyNetwork {
|
||||||
public:
|
public:
|
||||||
void begin() override {
|
void begin() override {
|
||||||
|
mAp.enable();
|
||||||
|
|
||||||
|
// static IP
|
||||||
setupIp([this](IPAddress ip, IPAddress gateway, IPAddress mask, IPAddress dns1, IPAddress dns2) -> bool {
|
setupIp([this](IPAddress ip, IPAddress gateway, IPAddress mask, IPAddress dns1, IPAddress dns2) -> bool {
|
||||||
return ETH.config(ip, gateway, mask, dns1, dns2);
|
return ETH.config(ip, gateway, mask, dns1, dns2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ETH.setHostname(mConfig->sys.deviceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tickNetworkLoop() override {
|
void tickNetworkLoop() override {
|
||||||
switch(mState) {
|
if(mAp.isEnabled())
|
||||||
|
mAp.tickLoop();
|
||||||
|
|
||||||
|
switch(mStatus) {
|
||||||
case NetworkState::DISCONNECTED:
|
case NetworkState::DISCONNECTED:
|
||||||
break;
|
if(mConnected) {
|
||||||
|
mConnected = false;
|
||||||
|
mOnNetworkCB(false);
|
||||||
|
mAp.enable();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/*switch (event) {
|
|
||||||
case ARDUINO_EVENT_ETH_START:
|
|
||||||
DPRINTLN(DBG_VERBOSE, F("ETH Started"));
|
|
||||||
|
|
||||||
if(String(mConfig->sys.deviceName) != "")
|
|
||||||
ETH.setHostname(mConfig->sys.deviceName);
|
|
||||||
else
|
|
||||||
ETH.setHostname(F("ESP32_W5500"));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARDUINO_EVENT_ETH_CONNECTED:
|
case NetworkState::CONNECTED:
|
||||||
DPRINTLN(DBG_VERBOSE, F("ETH Connected"));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARDUINO_EVENT_ETH_GOT_IP:
|
case NetworkState::GOT_IP:
|
||||||
if (!mEthConnected) {
|
mAp.disable();
|
||||||
welcome(ETH.localIP().toString(), F(" (Station)"));
|
|
||||||
|
|
||||||
mEthConnected = true;
|
if(!mConnected) {
|
||||||
|
mConnected = true;
|
||||||
|
ah::welcome(ETH.localIP().toString(), F("Station"));
|
||||||
|
MDNS.begin(mConfig->sys.deviceName);
|
||||||
mOnNetworkCB(true);
|
mOnNetworkCB(true);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
if (!MDNS.begin(mConfig->sys.deviceName)) {
|
}
|
||||||
DPRINTLN(DBG_ERROR, F("Error setting up MDNS responder!"));
|
|
||||||
} else {
|
|
||||||
DBGPRINT(F("mDNS established: "));
|
|
||||||
DBGPRINT(mConfig->sys.deviceName);
|
|
||||||
DBGPRINTLN(F(".local"));
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case ARDUINO_EVENT_ETH_DISCONNECTED:
|
String getIp(void) override {
|
||||||
DPRINTLN(DBG_INFO, F("ETH Disconnected"));
|
return ETH.localIP().toString();
|
||||||
mEthConnected = false;
|
}
|
||||||
mUdp.close();
|
|
||||||
mOnNetworkCB(false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARDUINO_EVENT_ETH_STOP:
|
void scanAvailNetworks(void) override {};
|
||||||
DPRINTLN(DBG_INFO, F("ETH Stopped"));
|
bool getAvailNetworks(JsonObject obj) override {
|
||||||
mEthConnected = false;
|
return false;
|
||||||
mUdp.close();
|
}
|
||||||
mOnNetworkCB(false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif /*ETHERNET*/
|
||||||
#endif /*__AHOY_ETHERNET_H__*/
|
#endif /*__AHOY_ETHERNET_H__*/
|
||||||
|
|
|
@ -7,9 +7,11 @@
|
||||||
#define __AHOY_NETWORK_H__
|
#define __AHOY_NETWORK_H__
|
||||||
|
|
||||||
#include "AhoyNetworkHelper.h"
|
#include "AhoyNetworkHelper.h"
|
||||||
#include <WiFiUdp.h>
|
#include <AsyncUDP.h>
|
||||||
#include "../config/settings.h"
|
#include "../config/settings.h"
|
||||||
#include "../utils/helper.h"
|
#include "../utils/helper.h"
|
||||||
|
#include "AhoyWifiAp.h"
|
||||||
|
#include "AsyncJson.h"
|
||||||
|
|
||||||
#if defined(ESP32)
|
#if defined(ESP32)
|
||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
|
@ -31,9 +33,15 @@ class AhoyNetwork {
|
||||||
mOnNetworkCB = onNetworkCB;
|
mOnNetworkCB = onNetworkCB;
|
||||||
mOnTimeCB = onTimeCB;
|
mOnTimeCB = onTimeCB;
|
||||||
|
|
||||||
|
if('\0' == mConfig->sys.deviceName[0])
|
||||||
|
snprintf(mConfig->sys.deviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME);
|
||||||
|
WiFi.hostname(mConfig->sys.deviceName);
|
||||||
|
|
||||||
|
mAp.setup(&mConfig->sys);
|
||||||
|
|
||||||
#if defined(ESP32)
|
#if defined(ESP32)
|
||||||
WiFi.onEvent([this](WiFiEvent_t event) -> void {
|
WiFi.onEvent([this](WiFiEvent_t event, arduino_event_info_t info) -> void {
|
||||||
this->OnEvent(event);
|
OnEvent(event);
|
||||||
});
|
});
|
||||||
#else
|
#else
|
||||||
wifiConnectHandler = WiFi.onStationModeConnected(
|
wifiConnectHandler = WiFi.onStationModeConnected(
|
||||||
|
@ -52,15 +60,15 @@ class AhoyNetwork {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isConnected() const {
|
bool isConnected() const {
|
||||||
return (mStatus == NetworkState.CONNECTED);
|
return (mStatus == NetworkState::CONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool updateNtpTime(void) {
|
bool updateNtpTime(void) {
|
||||||
if(CONNECTED != mStatus)
|
if(NetworkState::CONNECTED != mStatus)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
if (!mUdp.connected()) {
|
|
||||||
IPAddress timeServer;
|
IPAddress timeServer;
|
||||||
|
if (!mUdp.connected()) {
|
||||||
if (!WiFi.hostByName(mConfig->ntp.addr, timeServer))
|
if (!WiFi.hostByName(mConfig->ntp.addr, timeServer))
|
||||||
return false;
|
return false;
|
||||||
if (!mUdp.connect(timeServer, mConfig->ntp.port))
|
if (!mUdp.connect(timeServer, mConfig->ntp.port))
|
||||||
|
@ -78,17 +86,19 @@ class AhoyNetwork {
|
||||||
public:
|
public:
|
||||||
virtual void begin() = 0;
|
virtual void begin() = 0;
|
||||||
virtual void tickNetworkLoop() = 0;
|
virtual void tickNetworkLoop() = 0;
|
||||||
virtual void connectionEvent(WiFiStatus_t status) = 0;
|
virtual String getIp(void) = 0;
|
||||||
|
virtual void scanAvailNetworks(void) = 0;
|
||||||
|
virtual bool getAvailNetworks(JsonObject obj) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setupIp(void) {
|
void setupIp(std::function<bool(IPAddress ip, IPAddress gateway, IPAddress mask, IPAddress dns1, IPAddress dns2)> cb) {
|
||||||
if(mConfig->sys.ip.ip[0] != 0) {
|
if(mConfig->sys.ip.ip[0] != 0) {
|
||||||
IPAddress ip(mConfig->sys.ip.ip);
|
IPAddress ip(mConfig->sys.ip.ip);
|
||||||
IPAddress mask(mConfig->sys.ip.mask);
|
IPAddress mask(mConfig->sys.ip.mask);
|
||||||
IPAddress dns1(mConfig->sys.ip.dns1);
|
IPAddress dns1(mConfig->sys.ip.dns1);
|
||||||
IPAddress dns2(mConfig->sys.ip.dns2);
|
IPAddress dns2(mConfig->sys.ip.dns2);
|
||||||
IPAddress gateway(mConfig->sys.ip.gateway);
|
IPAddress gateway(mConfig->sys.ip.gateway);
|
||||||
if(!ETH.config(ip, gateway, mask, dns1, dns2))
|
if(cb(ip, gateway, mask, dns1, dns2))
|
||||||
DPRINTLN(DBG_ERROR, F("failed to set static IP!"));
|
DPRINTLN(DBG_ERROR, F("failed to set static IP!"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,25 +179,22 @@ class AhoyNetwork {
|
||||||
protected:
|
protected:
|
||||||
enum class NetworkState : uint8_t {
|
enum class NetworkState : uint8_t {
|
||||||
DISCONNECTED,
|
DISCONNECTED,
|
||||||
CONNECTING,
|
|
||||||
CONNECTED,
|
CONNECTED,
|
||||||
IN_AP_MODE,
|
GOT_IP
|
||||||
GOT_IP,
|
|
||||||
IN_STA_MODE,
|
|
||||||
RESET,
|
|
||||||
SCAN_READY
|
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
settings_t *mConfig = nullptr;
|
settings_t *mConfig = nullptr;
|
||||||
uint32_t *mUtcTimestamp = nullptr;
|
uint32_t *mUtcTimestamp = nullptr;
|
||||||
|
bool mConnected = false;
|
||||||
|
|
||||||
OnNetworkCB mOnNetworkCB;
|
OnNetworkCB mOnNetworkCB;
|
||||||
OnTimeCB mOnTimeCB;
|
OnTimeCB mOnTimeCB;
|
||||||
|
|
||||||
NetworkState mStatus = NetworkState.DISCONNECTED;
|
NetworkState mStatus = NetworkState::DISCONNECTED;
|
||||||
|
|
||||||
WiFiUDP mUdp; // for time server
|
AhoyWifiAp mAp;
|
||||||
|
AsyncUDP mUdp; // for time server
|
||||||
DNSServer mDns;
|
DNSServer mDns;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
20
src/network/AhoyNetworkHelper.cpp
Normal file
20
src/network/AhoyNetworkHelper.cpp
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// 2024 Ahoy, https://ahoydtu.de
|
||||||
|
// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "AhoyNetworkHelper.h"
|
||||||
|
|
||||||
|
namespace ah {
|
||||||
|
void welcome(String ip, String info) {
|
||||||
|
DBGPRINTLN(F("\n\n-------------------"));
|
||||||
|
DBGPRINTLN(F("Welcome to AHOY!"));
|
||||||
|
DBGPRINT(F("\npoint your browser to http://"));
|
||||||
|
DBGPRINT(ip);
|
||||||
|
DBGPRINT(" (");
|
||||||
|
DBGPRINT(info);
|
||||||
|
DBGPRINTLN(")");
|
||||||
|
DBGPRINTLN(F("to configure your device"));
|
||||||
|
DBGPRINTLN(F("-------------------\n"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,17 +13,7 @@
|
||||||
#include <DNSServer.h>
|
#include <DNSServer.h>
|
||||||
|
|
||||||
namespace ah {
|
namespace ah {
|
||||||
void welcome(String ip, String info) {
|
void welcome(String ip, String info);
|
||||||
DBGPRINTLN(F("\n\n-------------------"));
|
|
||||||
DBGPRINTLN(F("Welcome to AHOY!"));
|
|
||||||
DBGPRINT(F("\npoint your browser to http://"));
|
|
||||||
DBGPRINT(ip);
|
|
||||||
DBGPRINT(" (");
|
|
||||||
DBGPRINT(info);
|
|
||||||
DBGPRINTLN(")");
|
|
||||||
DBGPRINTLN(F("to configure your device"));
|
|
||||||
DBGPRINTLN(F("-------------------\n"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /*__AHOY_NETWORK_HELPER_H__*/
|
#endif /*__AHOY_NETWORK_HELPER_H__*/
|
||||||
|
|
|
@ -25,10 +25,10 @@ class AhoyWifiAp {
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable() {
|
void enable() {
|
||||||
|
if(mEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
ah::welcome(mIp.toString(), String(F("Password: ") + String(mCfg->apPwd)));
|
ah::welcome(mIp.toString(), String(F("Password: ") + String(mCfg->apPwd)));
|
||||||
if('\0' == mCfg->deviceName[0])
|
|
||||||
snprintf(mCfg->deviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME);
|
|
||||||
WiFi.hostname(mCfg->deviceName);
|
|
||||||
|
|
||||||
#if defined(ETHERNET)
|
#if defined(ETHERNET)
|
||||||
WiFi.mode(WIFI_AP);
|
WiFi.mode(WIFI_AP);
|
||||||
|
@ -45,6 +45,9 @@ class AhoyWifiAp {
|
||||||
}
|
}
|
||||||
|
|
||||||
void disable() {
|
void disable() {
|
||||||
|
if(!mEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
mDns.stop();
|
mDns.stop();
|
||||||
WiFi.softAPdisconnect();
|
WiFi.softAPdisconnect();
|
||||||
#if defined(ETHERNET)
|
#if defined(ETHERNET)
|
||||||
|
@ -56,7 +59,7 @@ class AhoyWifiAp {
|
||||||
mEnabled = false;
|
mEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getEnable() const {
|
bool isEnabled() const {
|
||||||
return mEnabled;
|
return mEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
112
src/network/AhoyWifiEsp32.h
Normal file
112
src/network/AhoyWifiEsp32.h
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// 2024 Ahoy, https://ahoydtu.de
|
||||||
|
// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef __AHOY_Wifi_ESP32_H__
|
||||||
|
#define __AHOY_Wifi_ESP32_H__
|
||||||
|
|
||||||
|
#if defined(ESP32) && !defined(ETHERNET)
|
||||||
|
#include <functional>
|
||||||
|
#include <AsyncUDP.h>
|
||||||
|
#include <Wifi.h>
|
||||||
|
#include "AhoyNetwork.h"
|
||||||
|
|
||||||
|
class AhoyWifi : public AhoyNetwork {
|
||||||
|
public:
|
||||||
|
void begin() override {
|
||||||
|
mAp.enable();
|
||||||
|
|
||||||
|
// static IP
|
||||||
|
setupIp([this](IPAddress ip, IPAddress gateway, IPAddress mask, IPAddress dns1, IPAddress dns2) -> bool {
|
||||||
|
return WiFi.config(ip, gateway, mask, dns1, dns2);
|
||||||
|
});
|
||||||
|
|
||||||
|
WiFi.setHostname(mConfig->sys.deviceName);
|
||||||
|
WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN);
|
||||||
|
WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL);
|
||||||
|
WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd, WIFI_ALL_CHANNEL_SCAN);
|
||||||
|
|
||||||
|
DBGPRINT(F("connect to network '")); Serial.flush();
|
||||||
|
DBGPRINT(mConfig->sys.stationSsid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tickNetworkLoop() override {
|
||||||
|
if(mAp.isEnabled())
|
||||||
|
mAp.tickLoop();
|
||||||
|
|
||||||
|
switch(mStatus) {
|
||||||
|
case NetworkState::DISCONNECTED:
|
||||||
|
if(mConnected) {
|
||||||
|
mConnected = false;
|
||||||
|
mOnNetworkCB(false);
|
||||||
|
mAp.enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WiFi.softAPgetStationNum() > 0) {
|
||||||
|
DBGPRINTLN(F("AP client connected"));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NetworkState::CONNECTED:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NetworkState::GOT_IP:
|
||||||
|
if(!mConnected) {
|
||||||
|
mAp.disable();
|
||||||
|
mConnected = true;
|
||||||
|
ah::welcome(WiFi.localIP().toString(), F("Station"));
|
||||||
|
MDNS.begin(mConfig->sys.deviceName);
|
||||||
|
mOnNetworkCB(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String getIp(void) override {
|
||||||
|
return WiFi.localIP().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void scanAvailNetworks(void) override {
|
||||||
|
if(!mScanActive) {
|
||||||
|
mScanActive = true;
|
||||||
|
WiFi.scanNetworks(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getAvailNetworks(JsonObject obj) override {
|
||||||
|
JsonArray nets = obj.createNestedArray(F("networks"));
|
||||||
|
|
||||||
|
int n = WiFi.scanComplete();
|
||||||
|
if (n < 0)
|
||||||
|
return false;
|
||||||
|
if(n > 0) {
|
||||||
|
int sort[n];
|
||||||
|
sortRSSI(&sort[0], n);
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
nets[i][F("ssid")] = WiFi.SSID(sort[i]);
|
||||||
|
nets[i][F("rssi")] = WiFi.RSSI(sort[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mScanActive = false;
|
||||||
|
WiFi.scanDelete();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void sortRSSI(int *sort, int n) {
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
sort[i] = i;
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
for (int j = i + 1; j < n; j++)
|
||||||
|
if (WiFi.RSSI(sort[j]) > WiFi.RSSI(sort[i]))
|
||||||
|
std::swap(sort[i], sort[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mScanActive = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*ESP32 & !ETHERNET*/
|
||||||
|
#endif /*__AHOY_Wifi_ESP32_H__*/
|
|
@ -16,10 +16,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#if defined(ETHERNET)
|
|
||||||
#include "../eth/ahoyeth.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../utils/dbg.h"
|
#include "../utils/dbg.h"
|
||||||
#include "../config/config.h"
|
#include "../config/config.h"
|
||||||
#include <espMqttClient.h>
|
#include <espMqttClient.h>
|
||||||
|
@ -56,7 +52,8 @@ class PubMqtt {
|
||||||
|
|
||||||
~PubMqtt() { }
|
~PubMqtt() { }
|
||||||
|
|
||||||
void setup(cfgMqtt_t *cfg_mqtt, const char *devName, const char *version, HMSYSTEM *sys, uint32_t *utcTs, uint32_t *uptime) {
|
void setup(IApp *app, cfgMqtt_t *cfg_mqtt, const char *devName, const char *version, HMSYSTEM *sys, uint32_t *utcTs, uint32_t *uptime) {
|
||||||
|
mApp = app;
|
||||||
mCfgMqtt = cfg_mqtt;
|
mCfgMqtt = cfg_mqtt;
|
||||||
mDevName = devName;
|
mDevName = devName;
|
||||||
mVersion = version;
|
mVersion = version;
|
||||||
|
@ -256,11 +253,7 @@ class PubMqtt {
|
||||||
|
|
||||||
publish(subtopics[MQTT_VERSION], mVersion, true);
|
publish(subtopics[MQTT_VERSION], mVersion, true);
|
||||||
publish(subtopics[MQTT_DEVICE], mDevName, true);
|
publish(subtopics[MQTT_DEVICE], mDevName, true);
|
||||||
#if defined(ETHERNET)
|
publish(subtopics[MQTT_IP_ADDR], mApp->getIp().c_str(), true);
|
||||||
publish(subtopics[MQTT_IP_ADDR], ETH.localIP().toString().c_str(), true);
|
|
||||||
#else
|
|
||||||
publish(subtopics[MQTT_IP_ADDR], WiFi.localIP().toString().c_str(), true);
|
|
||||||
#endif
|
|
||||||
tickerMinute();
|
tickerMinute();
|
||||||
publish(mLwtTopic.data(), mqttStr[MQTT_STR_LWT_CONN], true, false);
|
publish(mLwtTopic.data(), mqttStr[MQTT_STR_LWT_CONN], true, false);
|
||||||
|
|
||||||
|
@ -611,6 +604,7 @@ class PubMqtt {
|
||||||
|
|
||||||
espMqttClient mClient;
|
espMqttClient mClient;
|
||||||
cfgMqtt_t *mCfgMqtt = nullptr;
|
cfgMqtt_t *mCfgMqtt = nullptr;
|
||||||
|
IApp *mApp;
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
WiFiEventHandler mHWifiCon, mHWifiDiscon;
|
WiFiEventHandler mHWifiCon, mHWifiDiscon;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -893,7 +893,7 @@ class RestApi {
|
||||||
mApp->getAvailNetworks(obj);
|
mApp->getAvailNetworks(obj);
|
||||||
}
|
}
|
||||||
void getWifiIp(JsonObject obj) {
|
void getWifiIp(JsonObject obj) {
|
||||||
obj[F("ip")] = mApp->getStationIp();
|
obj[F("ip")] = mApp->getIp();
|
||||||
}
|
}
|
||||||
#endif /* !defined(ETHERNET) */
|
#endif /* !defined(ETHERNET) */
|
||||||
|
|
||||||
|
@ -1048,7 +1048,7 @@ class RestApi {
|
||||||
snprintf(mConfig->sys.stationSsid, SSID_LEN, "%s", jsonIn[F("ssid")].as<const char*>());
|
snprintf(mConfig->sys.stationSsid, SSID_LEN, "%s", jsonIn[F("ssid")].as<const char*>());
|
||||||
snprintf(mConfig->sys.stationPwd, PWD_LEN, "%s", jsonIn[F("pwd")].as<const char*>());
|
snprintf(mConfig->sys.stationPwd, PWD_LEN, "%s", jsonIn[F("pwd")].as<const char*>());
|
||||||
mApp->saveSettings(false); // without reboot
|
mApp->saveSettings(false); // without reboot
|
||||||
mApp->setStopApAllowedMode(false);
|
//mApp->setStopApAllowedMode(false);
|
||||||
mApp->setupStation();
|
mApp->setupStation();
|
||||||
}
|
}
|
||||||
#endif /* !defined(ETHERNET */
|
#endif /* !defined(ETHERNET */
|
||||||
|
|
|
@ -1,490 +0,0 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// 2024 Ahoy, https://ahoydtu.de
|
|
||||||
// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#if !defined(ETHERNET)
|
|
||||||
#if defined(ESP32) && defined(F)
|
|
||||||
#undef F
|
|
||||||
#define F(sl) (sl)
|
|
||||||
#endif
|
|
||||||
#include "ahoywifi.h"
|
|
||||||
|
|
||||||
#if defined(ESP32)
|
|
||||||
#include <ESPmDNS.h>
|
|
||||||
#else
|
|
||||||
#include <ESP8266mDNS.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// NTP CONFIG
|
|
||||||
#define NTP_PACKET_SIZE 48
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
ahoywifi::ahoywifi() : mApIp(192, 168, 4, 1) {}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: ESP32 has native strongest AP support!
|
|
||||||
* WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN);
|
|
||||||
WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL);
|
|
||||||
*/
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void ahoywifi::setup(settings_t *config, uint32_t *utcTimestamp, appWifiCb cb, OnTimeCB onTimeCb) {
|
|
||||||
mConfig = config;
|
|
||||||
mUtcTimestamp = utcTimestamp;
|
|
||||||
mAppWifiCb = cb;
|
|
||||||
mOnTimeCb = onTimeCb;
|
|
||||||
|
|
||||||
mGotDisconnect = false;
|
|
||||||
mStaConn = DISCONNECTED;
|
|
||||||
mCnt = 0;
|
|
||||||
mScanActive = false;
|
|
||||||
mScanCnt = 0;
|
|
||||||
mStopApAllowed = true;
|
|
||||||
|
|
||||||
#if defined(ESP8266)
|
|
||||||
wifiConnectHandler = WiFi.onStationModeConnected(std::bind(&ahoywifi::onConnect, this, std::placeholders::_1));
|
|
||||||
wifiGotIPHandler = WiFi.onStationModeGotIP(std::bind(&ahoywifi::onGotIP, this, std::placeholders::_1));
|
|
||||||
wifiDisconnectHandler = WiFi.onStationModeDisconnected(std::bind(&ahoywifi::onDisconnect, this, std::placeholders::_1));
|
|
||||||
#else
|
|
||||||
WiFi.onEvent(std::bind(&ahoywifi::onWiFiEvent, this, std::placeholders::_1));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
setupWifi(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void ahoywifi::setupWifi(bool startAP = false) {
|
|
||||||
#if !defined(FB_WIFI_OVERRIDDEN)
|
|
||||||
if(startAP) {
|
|
||||||
setupAp();
|
|
||||||
delay(1000);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if !defined(AP_ONLY)
|
|
||||||
#if defined(FB_WIFI_OVERRIDDEN)
|
|
||||||
snprintf(mConfig->sys.stationSsid, SSID_LEN, "%s", FB_WIFI_SSID);
|
|
||||||
snprintf(mConfig->sys.stationPwd, PWD_LEN, "%s", FB_WIFI_PWD);
|
|
||||||
setupStation();
|
|
||||||
#else
|
|
||||||
if(mConfig->valid) {
|
|
||||||
if(strncmp(mConfig->sys.stationSsid, FB_WIFI_SSID, 14) != 0)
|
|
||||||
setupStation();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ahoywifi::tickWifiLoop() {
|
|
||||||
static const uint8_t TIMEOUT = 20;
|
|
||||||
static const uint8_t SCAN_TIMEOUT = 10;
|
|
||||||
#if !defined(AP_ONLY)
|
|
||||||
|
|
||||||
mCnt++;
|
|
||||||
|
|
||||||
switch (mStaConn) {
|
|
||||||
case IN_STA_MODE:
|
|
||||||
// Nothing to do
|
|
||||||
if (mGotDisconnect) {
|
|
||||||
mStaConn = RESET;
|
|
||||||
}
|
|
||||||
#if !defined(ESP32)
|
|
||||||
MDNS.update();
|
|
||||||
if(WiFi.channel() > 11)
|
|
||||||
mWasInCh12to14 = true;
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
case IN_AP_MODE:
|
|
||||||
if ((WiFi.softAPgetStationNum() == 0) || (!mStopApAllowed)) {
|
|
||||||
mCnt = 0;
|
|
||||||
mDns.stop();
|
|
||||||
WiFi.mode(WIFI_AP_STA);
|
|
||||||
mStaConn = DISCONNECTED;
|
|
||||||
} else {
|
|
||||||
mDns.processNextRequest();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DISCONNECTED:
|
|
||||||
if ((WiFi.softAPgetStationNum() > 0) && (mStopApAllowed)) {
|
|
||||||
mStaConn = IN_AP_MODE;
|
|
||||||
// first time switch to AP Mode
|
|
||||||
if (mScanActive) {
|
|
||||||
WiFi.scanDelete();
|
|
||||||
mScanActive = false;
|
|
||||||
}
|
|
||||||
DBGPRINTLN(F("AP client connected"));
|
|
||||||
welcome(mApIp.toString(), "");
|
|
||||||
WiFi.mode(WIFI_AP);
|
|
||||||
mDns.start(53, "*", mApIp);
|
|
||||||
mAppWifiCb(true);
|
|
||||||
mDns.processNextRequest();
|
|
||||||
return;
|
|
||||||
} else if (!mScanActive) {
|
|
||||||
DBGPRINT(F("scanning APs with SSID "));
|
|
||||||
DBGPRINTLN(String(mConfig->sys.stationSsid));
|
|
||||||
mScanCnt = 0;
|
|
||||||
mCnt = 0;
|
|
||||||
mScanActive = true;
|
|
||||||
#if defined(ESP8266)
|
|
||||||
WiFi.scanNetworks(true, true, 0U, ([this]() {
|
|
||||||
if (mConfig->sys.isHidden)
|
|
||||||
return (uint8_t*)NULL;
|
|
||||||
return (uint8_t*)(mConfig->sys.stationSsid);
|
|
||||||
})());
|
|
||||||
#else
|
|
||||||
WiFi.scanNetworks(true, true, false, 300U, 0U, ([this]() {
|
|
||||||
if (mConfig->sys.isHidden)
|
|
||||||
return (char*)NULL;
|
|
||||||
return (mConfig->sys.stationSsid);
|
|
||||||
})());
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
} else if(getBSSIDs()) {
|
|
||||||
// Scan ready
|
|
||||||
mStaConn = SCAN_READY;
|
|
||||||
} else {
|
|
||||||
// In case of a timeout, what do we do?
|
|
||||||
// For now we start scanning again as the original code did.
|
|
||||||
// Would be better to into PA mode
|
|
||||||
|
|
||||||
if (isTimeout(SCAN_TIMEOUT)) {
|
|
||||||
WiFi.scanDelete();
|
|
||||||
mScanActive = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SCAN_READY:
|
|
||||||
mStaConn = CONNECTING;
|
|
||||||
mCnt = 0;
|
|
||||||
DBGPRINT(F("try to connect to AP with BSSID:"));
|
|
||||||
uint8_t bssid[6];
|
|
||||||
for (int j = 0; j < 6; j++) {
|
|
||||||
bssid[j] = mBSSIDList.front();
|
|
||||||
mBSSIDList.pop_front();
|
|
||||||
DBGPRINT(" " + String(bssid[j], HEX));
|
|
||||||
}
|
|
||||||
DBGPRINTLN("");
|
|
||||||
mGotDisconnect = false;
|
|
||||||
WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd, 0, &bssid[0]);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case CONNECTING:
|
|
||||||
if (isTimeout(TIMEOUT)) {
|
|
||||||
WiFi.disconnect();
|
|
||||||
mStaConn = mBSSIDList.empty() ? DISCONNECTED : SCAN_READY;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CONNECTED:
|
|
||||||
// Connection but no IP yet
|
|
||||||
if (isTimeout(TIMEOUT) || mGotDisconnect) {
|
|
||||||
mStaConn = RESET;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GOT_IP:
|
|
||||||
welcome(WiFi.localIP().toString(), F(" (Station)"));
|
|
||||||
if(mStopApAllowed) {
|
|
||||||
WiFi.softAPdisconnect();
|
|
||||||
WiFi.mode(WIFI_STA);
|
|
||||||
DBGPRINTLN(F("[WiFi] AP disabled"));
|
|
||||||
delay(100);
|
|
||||||
}
|
|
||||||
mAppWifiCb(true);
|
|
||||||
mGotDisconnect = false;
|
|
||||||
mStaConn = IN_STA_MODE;
|
|
||||||
|
|
||||||
if (!MDNS.begin(mConfig->sys.deviceName)) {
|
|
||||||
DPRINTLN(DBG_ERROR, F("Error setting up MDNS responder!"));
|
|
||||||
} else {
|
|
||||||
DBGPRINT(F("mDNS established: "));
|
|
||||||
DBGPRINT(mConfig->sys.deviceName);
|
|
||||||
DBGPRINTLN(F(".local"));
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case RESET:
|
|
||||||
mGotDisconnect = false;
|
|
||||||
mStaConn = DISCONNECTED;
|
|
||||||
mCnt = 5; // try to reconnect in 5 sec
|
|
||||||
setupWifi(); // reconnect with AP / Station setup
|
|
||||||
mAppWifiCb(false);
|
|
||||||
DPRINTLN(DBG_INFO, "[WiFi] Connection Lost");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DBGPRINTLN(F("Unhandled status"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void ahoywifi::setupAp(void) {
|
|
||||||
DPRINTLN(DBG_VERBOSE, F("wifi::setupAp"));
|
|
||||||
|
|
||||||
DBGPRINTLN(F("\n---------\nAhoyDTU Info:"));
|
|
||||||
DBGPRINT(F("Version: "));
|
|
||||||
DBGPRINT(String(VERSION_MAJOR));
|
|
||||||
DBGPRINT(F("."));
|
|
||||||
DBGPRINT(String(VERSION_MINOR));
|
|
||||||
DBGPRINT(F("."));
|
|
||||||
DBGPRINTLN(String(VERSION_PATCH));
|
|
||||||
DBGPRINT(F("Github Hash: "));
|
|
||||||
DBGPRINTLN(String(AUTO_GIT_HASH));
|
|
||||||
|
|
||||||
DBGPRINT(F("\n---------\nAP MODE\nSSID: "));
|
|
||||||
DBGPRINTLN(WIFI_AP_SSID);
|
|
||||||
DBGPRINT(F("PWD: "));
|
|
||||||
DBGPRINTLN(mConfig->sys.apPwd);
|
|
||||||
DBGPRINT(F("IP Address: http://"));
|
|
||||||
DBGPRINTLN(mApIp.toString());
|
|
||||||
DBGPRINTLN(F("---------\n"));
|
|
||||||
|
|
||||||
if(String(mConfig->sys.deviceName) != "")
|
|
||||||
WiFi.hostname(mConfig->sys.deviceName);
|
|
||||||
|
|
||||||
WiFi.mode(WIFI_AP_STA);
|
|
||||||
WiFi.softAPConfig(mApIp, mApIp, IPAddress(255, 255, 255, 0));
|
|
||||||
WiFi.softAP(WIFI_AP_SSID, mConfig->sys.apPwd);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void ahoywifi::setupStation(void) {
|
|
||||||
DPRINTLN(DBG_VERBOSE, F("wifi::setupStation"));
|
|
||||||
if(mConfig->sys.ip.ip[0] != 0) {
|
|
||||||
IPAddress ip(mConfig->sys.ip.ip);
|
|
||||||
IPAddress mask(mConfig->sys.ip.mask);
|
|
||||||
IPAddress dns1(mConfig->sys.ip.dns1);
|
|
||||||
IPAddress dns2(mConfig->sys.ip.dns2);
|
|
||||||
IPAddress gateway(mConfig->sys.ip.gateway);
|
|
||||||
if(!WiFi.config(ip, gateway, mask, dns1, dns2))
|
|
||||||
DPRINTLN(DBG_ERROR, F("failed to set static IP!"));
|
|
||||||
}
|
|
||||||
mBSSIDList.clear();
|
|
||||||
if(String(mConfig->sys.deviceName) != "")
|
|
||||||
WiFi.hostname(mConfig->sys.deviceName);
|
|
||||||
WiFi.mode(WIFI_AP_STA);
|
|
||||||
|
|
||||||
DBGPRINT(F("connect to network '"));
|
|
||||||
DBGPRINT(mConfig->sys.stationSsid);
|
|
||||||
DBGPRINTLN(F("' ..."));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
bool ahoywifi::updateNtpTime(void) {
|
|
||||||
if(IN_STA_MODE != mStaConn)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
IPAddress timeServer;
|
|
||||||
uint8_t buf[NTP_PACKET_SIZE];
|
|
||||||
uint8_t retry = 0;
|
|
||||||
|
|
||||||
if (WiFi.hostByName(mConfig->ntp.addr, timeServer) != 1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
mUdp.begin(mConfig->ntp.port);
|
|
||||||
sendNTPpacket(timeServer);
|
|
||||||
|
|
||||||
while(retry++ < 5) {
|
|
||||||
int wait = 150;
|
|
||||||
while(--wait) {
|
|
||||||
if(NTP_PACKET_SIZE <= mUdp.parsePacket()) {
|
|
||||||
uint64_t secsSince1900;
|
|
||||||
mUdp.read(buf, NTP_PACKET_SIZE);
|
|
||||||
secsSince1900 = ((uint64_t)buf[40] << 24);
|
|
||||||
secsSince1900 |= (buf[41] << 16);
|
|
||||||
secsSince1900 |= (buf[42] << 8);
|
|
||||||
secsSince1900 |= (buf[43] );
|
|
||||||
|
|
||||||
*mUtcTimestamp = secsSince1900 - 2208988800UL; // UTC time
|
|
||||||
DPRINTLN(DBG_INFO, "[NTP]: " + ah::getDateTimeStr(*mUtcTimestamp) + " UTC");
|
|
||||||
mOnTimeCb(true);
|
|
||||||
return true;
|
|
||||||
} else
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINTLN(DBG_INFO, F("[NTP]: getNtpTime failed"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void ahoywifi::sendNTPpacket(IPAddress& address) {
|
|
||||||
//DPRINTLN(DBG_VERBOSE, F("wifi::sendNTPpacket"));
|
|
||||||
uint8_t buf[NTP_PACKET_SIZE] = {0};
|
|
||||||
|
|
||||||
buf[0] = B11100011; // LI, Version, Mode
|
|
||||||
buf[1] = 0; // Stratum
|
|
||||||
buf[2] = 6; // Max Interval between messages in seconds
|
|
||||||
buf[3] = 0xEC; // Clock Precision
|
|
||||||
// bytes 4 - 11 are for Root Delay and Dispersion and were set to 0 by memset
|
|
||||||
buf[12] = 49; // four-byte reference ID identifying
|
|
||||||
buf[13] = 0x4E;
|
|
||||||
buf[14] = 49;
|
|
||||||
buf[15] = 52;
|
|
||||||
|
|
||||||
mUdp.beginPacket(address, 123); // NTP request, port 123
|
|
||||||
mUdp.write(buf, NTP_PACKET_SIZE);
|
|
||||||
mUdp.endPacket();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void ahoywifi::sortRSSI(int *sort, int n) {
|
|
||||||
for (int i = 0; i < n; i++)
|
|
||||||
sort[i] = i;
|
|
||||||
for (int i = 0; i < n; i++)
|
|
||||||
for (int j = i + 1; j < n; j++)
|
|
||||||
if (WiFi.RSSI(sort[j]) > WiFi.RSSI(sort[i]))
|
|
||||||
std::swap(sort[i], sort[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void ahoywifi::scanAvailNetworks(void) {
|
|
||||||
if(!mScanActive) {
|
|
||||||
mScanActive = true;
|
|
||||||
if(WIFI_AP == WiFi.getMode())
|
|
||||||
WiFi.mode(WIFI_AP_STA);
|
|
||||||
WiFi.scanNetworks(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
bool ahoywifi::getAvailNetworks(JsonObject obj) {
|
|
||||||
JsonArray nets = obj.createNestedArray("networks");
|
|
||||||
|
|
||||||
int n = WiFi.scanComplete();
|
|
||||||
if (n < 0)
|
|
||||||
return false;
|
|
||||||
if(n > 0) {
|
|
||||||
int sort[n];
|
|
||||||
sortRSSI(&sort[0], n);
|
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
nets[i]["ssid"] = WiFi.SSID(sort[i]);
|
|
||||||
nets[i]["rssi"] = WiFi.RSSI(sort[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mScanActive = false;
|
|
||||||
WiFi.scanDelete();
|
|
||||||
if(mStaConn == IN_AP_MODE)
|
|
||||||
WiFi.mode(WIFI_AP);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
bool ahoywifi::getBSSIDs() {
|
|
||||||
bool result = false;
|
|
||||||
int n = WiFi.scanComplete();
|
|
||||||
if (n < 0) {
|
|
||||||
if (++mScanCnt < 20)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(n > 0) {
|
|
||||||
mBSSIDList.clear();
|
|
||||||
int sort[n];
|
|
||||||
sortRSSI(&sort[0], n);
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
DBGPRINT("BSSID " + String(i) + ":");
|
|
||||||
uint8_t *bssid = WiFi.BSSID(sort[i]);
|
|
||||||
for (int j = 0; j < 6; j++){
|
|
||||||
DBGPRINT(" " + String(bssid[j], HEX));
|
|
||||||
mBSSIDList.push_back(bssid[j]);
|
|
||||||
}
|
|
||||||
DBGPRINTLN("");
|
|
||||||
}
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
mScanActive = false;
|
|
||||||
WiFi.scanDelete();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void ahoywifi::connectionEvent(WiFiStatus_t status) {
|
|
||||||
DPRINTLN(DBG_INFO, "connectionEvent");
|
|
||||||
|
|
||||||
switch(status) {
|
|
||||||
case CONNECTED:
|
|
||||||
if(mStaConn != CONNECTED) {
|
|
||||||
mStaConn = CONNECTED;
|
|
||||||
mGotDisconnect = false;
|
|
||||||
DBGPRINTLN(F("\n[WiFi] Connected"));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GOT_IP:
|
|
||||||
mStaConn = GOT_IP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DISCONNECTED:
|
|
||||||
mGotDisconnect = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
#if defined(ESP8266)
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
void ahoywifi::onConnect(const WiFiEventStationModeConnected& event) {
|
|
||||||
connectionEvent(CONNECTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
void ahoywifi::onGotIP(const WiFiEventStationModeGotIP& event) {
|
|
||||||
connectionEvent(GOT_IP);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
void ahoywifi::onDisconnect(const WiFiEventStationModeDisconnected& event) {
|
|
||||||
connectionEvent(DISCONNECTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
void ahoywifi::onWiFiEvent(WiFiEvent_t event) {
|
|
||||||
DBGPRINT(F("Wifi event: "));
|
|
||||||
DBGPRINTLN(String(event));
|
|
||||||
|
|
||||||
switch(event) {
|
|
||||||
case SYSTEM_EVENT_STA_CONNECTED:
|
|
||||||
connectionEvent(CONNECTED);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SYSTEM_EVENT_STA_GOT_IP:
|
|
||||||
connectionEvent(GOT_IP);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SYSTEM_EVENT_STA_DISCONNECTED:
|
|
||||||
connectionEvent(DISCONNECTED);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void ahoywifi::welcome(String ip, String mode) {
|
|
||||||
DBGPRINTLN(F("\n\n--------------------------------"));
|
|
||||||
DBGPRINTLN(F("Welcome to AHOY!"));
|
|
||||||
DBGPRINT(F("\npoint your browser to http://"));
|
|
||||||
DBGPRINT(ip);
|
|
||||||
DBGPRINTLN(mode);
|
|
||||||
DBGPRINTLN(F("to configure your device"));
|
|
||||||
DBGPRINTLN(F("--------------------------------\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !defined(ETHERNET) */
|
|
|
@ -1,100 +0,0 @@
|
||||||
//------------------------------------//-----------------------------------------------------------------------------
|
|
||||||
// 2024 Ahoy, https://github.com/lumpapu/ahoy
|
|
||||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#if !defined(ETHERNET)
|
|
||||||
#ifndef __AHOYWIFI_H__
|
|
||||||
#define __AHOYWIFI_H__
|
|
||||||
|
|
||||||
#include "../utils/dbg.h"
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <list>
|
|
||||||
#include <WiFiUdp.h>
|
|
||||||
#include <DNSServer.h>
|
|
||||||
#include "ESPAsyncWebServer.h"
|
|
||||||
|
|
||||||
#include "../config/settings.h"
|
|
||||||
|
|
||||||
class app;
|
|
||||||
|
|
||||||
class ahoywifi {
|
|
||||||
public:
|
|
||||||
typedef std::function<void(bool)> appWifiCb;
|
|
||||||
typedef std::function<void(bool)> OnTimeCB;
|
|
||||||
|
|
||||||
ahoywifi();
|
|
||||||
|
|
||||||
|
|
||||||
void setup(settings_t *config, uint32_t *utcTimestamp, appWifiCb cb, OnTimeCB onTimeCB);
|
|
||||||
void tickWifiLoop(void);
|
|
||||||
bool updateNtpTime(void);
|
|
||||||
void scanAvailNetworks(void);
|
|
||||||
bool getAvailNetworks(JsonObject obj);
|
|
||||||
void setStopApAllowedMode(bool allowed) {
|
|
||||||
mStopApAllowed = allowed;
|
|
||||||
}
|
|
||||||
String getStationIp(void) {
|
|
||||||
return WiFi.localIP().toString();
|
|
||||||
}
|
|
||||||
void setupStation(void);
|
|
||||||
|
|
||||||
bool getWasInCh12to14() const {
|
|
||||||
return mWasInCh12to14;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef enum WiFiStatus {
|
|
||||||
DISCONNECTED = 0,
|
|
||||||
SCAN_READY,
|
|
||||||
CONNECTING,
|
|
||||||
CONNECTED,
|
|
||||||
IN_AP_MODE,
|
|
||||||
GOT_IP,
|
|
||||||
IN_STA_MODE,
|
|
||||||
RESET
|
|
||||||
} WiFiStatus_t;
|
|
||||||
|
|
||||||
void setupWifi(bool startAP);
|
|
||||||
void setupAp(void);
|
|
||||||
void sendNTPpacket(IPAddress& address);
|
|
||||||
void sortRSSI(int *sort, int n);
|
|
||||||
bool getBSSIDs(void);
|
|
||||||
void connectionEvent(WiFiStatus_t status);
|
|
||||||
bool isTimeout(uint8_t timeout) { return (mCnt % timeout) == 0; }
|
|
||||||
|
|
||||||
#if defined(ESP8266)
|
|
||||||
void onConnect(const WiFiEventStationModeConnected& event);
|
|
||||||
void onGotIP(const WiFiEventStationModeGotIP& event);
|
|
||||||
void onDisconnect(const WiFiEventStationModeDisconnected& event);
|
|
||||||
#else
|
|
||||||
void onWiFiEvent(WiFiEvent_t event);
|
|
||||||
#endif
|
|
||||||
void welcome(String ip, String mode);
|
|
||||||
|
|
||||||
|
|
||||||
settings_t *mConfig = nullptr;
|
|
||||||
appWifiCb mAppWifiCb;
|
|
||||||
OnTimeCB mOnTimeCb;
|
|
||||||
|
|
||||||
DNSServer mDns;
|
|
||||||
IPAddress mApIp;
|
|
||||||
WiFiUDP mUdp; // for time server
|
|
||||||
#if defined(ESP8266)
|
|
||||||
WiFiEventHandler wifiConnectHandler, wifiDisconnectHandler, wifiGotIPHandler;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WiFiStatus_t mStaConn = DISCONNECTED;
|
|
||||||
uint8_t mCnt = 0;
|
|
||||||
uint32_t *mUtcTimestamp = nullptr;
|
|
||||||
|
|
||||||
uint8_t mScanCnt = 0;
|
|
||||||
bool mScanActive = false;
|
|
||||||
bool mGotDisconnect = false;
|
|
||||||
std::list<uint8_t> mBSSIDList;
|
|
||||||
bool mStopApAllowed = false;
|
|
||||||
bool mWasInCh12to14 = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*__AHOYWIFI_H__*/
|
|
||||||
#endif /* !defined(ETHERNET) */
|
|
Loading…
Add table
Reference in a new issue