2020-10-25 20:35:34 +01:00
|
|
|
/*
|
|
|
|
***************************************************************************
|
|
|
|
** Program : networkStuff.h
|
2021-02-25 20:12:51 +01:00
|
|
|
**
|
2021-11-06 16:03:20 +01:00
|
|
|
** Version : v0.9.0
|
2021-02-25 20:12:51 +01:00
|
|
|
**
|
|
|
|
** Copyright (c) 2021 Robert van den Breemen
|
2020-10-25 20:35:34 +01:00
|
|
|
**
|
2021-01-11 00:37:30 +01:00
|
|
|
** Copyright (c) 2021 Robert van den Breemen
|
2020-12-12 01:34:41 +01:00
|
|
|
** based on Framework ESP8266 from Willem Aandewiel
|
2020-10-25 20:35:34 +01:00
|
|
|
**
|
|
|
|
** TERMS OF USE: MIT License. See bottom of file.
|
|
|
|
***************************************************************************
|
|
|
|
** Usage:
|
|
|
|
**
|
|
|
|
** #define HOSTNAME thisProject
|
|
|
|
**
|
|
|
|
** setup()
|
|
|
|
** {
|
|
|
|
** startTelnet();
|
|
|
|
** startWiFi(_HOSTNAME, 240); // timeout 4 minuten
|
|
|
|
** startMDNS(_HOSTNAME);
|
|
|
|
** httpServer.on("/index", <sendIndexPage>);
|
|
|
|
** httpServer.on("/index.html",<sendIndexPage>);
|
|
|
|
** httpServer.begin();
|
|
|
|
** }
|
|
|
|
**
|
|
|
|
** loop()
|
|
|
|
** {
|
|
|
|
** handleWiFi();
|
|
|
|
** MDNS.update();
|
|
|
|
** httpServer.handleClient();
|
|
|
|
** .
|
|
|
|
** .
|
|
|
|
** }
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2021-02-14 14:31:21 +01:00
|
|
|
#include <ESP8266WiFi.h> // ESP8266 Core WiFi Library
|
2020-10-25 20:35:34 +01:00
|
|
|
#include <ESP8266WebServer.h> // Version 1.0.0 - part of ESP8266 Core https://github.com/esp8266/Arduino
|
|
|
|
#include <ESP8266mDNS.h> // part of ESP8266 Core https://github.com/esp8266/Arduino
|
2021-02-14 14:31:21 +01:00
|
|
|
#include <ESP8266HTTPClient.h>
|
2021-03-06 16:42:57 +01:00
|
|
|
#include <ESP8266LLMNR.h>
|
2020-10-25 20:35:34 +01:00
|
|
|
|
|
|
|
#include <WiFiUdp.h> // part of ESP8266 Core https://github.com/esp8266/Arduino
|
|
|
|
//#include "ESP8266HTTPUpdateServer.h"
|
2021-01-11 09:12:07 +01:00
|
|
|
#include "OTGW-ModUpdateServer.h" // <<special version for Nodoshop Watchdog needed>>
|
2020-10-25 20:35:34 +01:00
|
|
|
#include "updateServerHtml.h"
|
2020-12-10 13:24:40 +01:00
|
|
|
#include <WiFiManager.h> // version 2.0.4-beta - use latest development branch - https://github.com/tzapu/WiFiManager
|
2020-10-25 20:35:34 +01:00
|
|
|
// included in main program: #include <TelnetStream.h> // Version 0.0.1 - https://github.com/jandrassy/TelnetStream
|
|
|
|
|
2021-01-30 16:00:16 +01:00
|
|
|
//#include <FS.h> // part of ESP8266 Core https://github.com/esp8266/Arduino
|
|
|
|
#include <LittleFS.h>
|
2020-10-25 20:35:34 +01:00
|
|
|
|
2021-10-16 20:36:00 +02:00
|
|
|
//Use the NTP SDK ESP 8266
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
enum NtpStatus_t {
|
|
|
|
TIME_NOTSET,
|
|
|
|
TIME_SYNC,
|
|
|
|
TIME_WAITFORSYNC,
|
|
|
|
TIME_NEEDSYNC
|
|
|
|
};
|
|
|
|
|
|
|
|
NtpStatus_t NtpStatus = TIME_NOTSET;
|
|
|
|
time_t NtpLastSync = 0; //last sync moment in EPOCH seconds
|
|
|
|
|
2020-10-25 20:35:34 +01:00
|
|
|
ESP8266WebServer httpServer (80);
|
|
|
|
ESP8266HTTPUpdateServer httpUpdater(true);
|
|
|
|
|
2021-01-30 16:00:16 +01:00
|
|
|
static FSInfo LittleFSinfo;
|
|
|
|
bool LittleFSmounted;
|
2020-10-25 20:35:34 +01:00
|
|
|
bool isConnected = false;
|
|
|
|
|
2021-03-14 21:58:35 +01:00
|
|
|
#define WM_DEBUG_PORT OTGWSerial
|
|
|
|
|
2020-10-25 20:35:34 +01:00
|
|
|
//gets called when WiFiManager enters configuration mode
|
|
|
|
//===========================================================================================
|
|
|
|
void configModeCallback (WiFiManager *myWiFiManager)
|
|
|
|
{
|
|
|
|
DebugTln(F("Entered config mode\r"));
|
|
|
|
DebugTln(WiFi.softAPIP().toString());
|
|
|
|
//if you used auto generated SSID, print it
|
|
|
|
DebugTln(myWiFiManager->getConfigPortalSSID());
|
|
|
|
|
|
|
|
} // configModeCallback()
|
|
|
|
|
|
|
|
|
|
|
|
//===========================================================================================
|
|
|
|
void startWiFi(const char* hostname, int timeOut)
|
2020-12-10 13:24:40 +01:00
|
|
|
{
|
|
|
|
WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
|
|
|
|
|
2020-10-25 20:35:34 +01:00
|
|
|
WiFiManager manageWiFi;
|
|
|
|
uint32_t lTime = millis();
|
|
|
|
String thisAP = String(hostname) + "-" + WiFi.macAddress();
|
|
|
|
|
2021-02-08 00:13:52 +01:00
|
|
|
OTGWSerial.println("Start Wifi ...");
|
2020-10-25 20:35:34 +01:00
|
|
|
manageWiFi.setDebugOutput(true);
|
2020-12-10 00:32:43 +01:00
|
|
|
|
|
|
|
//--- next line in release needs to be commented out!
|
2020-12-10 09:49:15 +01:00
|
|
|
// manageWiFi.resetSettings();
|
2020-12-10 00:32:43 +01:00
|
|
|
|
2020-10-25 20:35:34 +01:00
|
|
|
//--- set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
|
|
|
|
manageWiFi.setAPCallback(configModeCallback);
|
|
|
|
|
|
|
|
//--- sets timeout until configuration portal gets turned off
|
|
|
|
//--- useful to make it all retry or go to sleep in seconds
|
|
|
|
//manageWiFi.setTimeout(240); // 4 minuten
|
|
|
|
manageWiFi.setTimeout(timeOut); // in seconden ...
|
|
|
|
|
|
|
|
//--- fetches ssid and pass and tries to connect
|
|
|
|
//--- if it does not connect it starts an access point with the specified name
|
|
|
|
//--- here "<HOSTNAME>-<MAC>"
|
|
|
|
//--- and goes into a blocking loop awaiting configuration
|
2021-03-14 21:58:35 +01:00
|
|
|
OTGWSerial.printf("AutoConnect to: %s\r\n", thisAP.c_str());
|
2020-12-10 00:32:43 +01:00
|
|
|
if (!manageWiFi.autoConnect(thisAP.c_str()))
|
2020-10-25 20:35:34 +01:00
|
|
|
{
|
2020-12-10 00:32:43 +01:00
|
|
|
//-- fail to connect? Have you tried turning it off and on again?
|
2020-10-25 20:35:34 +01:00
|
|
|
DebugTln(F("failed to connect and hit timeout"));
|
2020-12-10 00:32:43 +01:00
|
|
|
delay(2000); // Enough time for messages to be sent.
|
|
|
|
ESP.restart();
|
|
|
|
delay(5000); // Enough time to ensure we don't return.
|
2020-10-25 20:35:34 +01:00
|
|
|
}
|
2020-12-10 13:24:40 +01:00
|
|
|
|
2021-10-24 10:53:18 +02:00
|
|
|
// WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
|
|
|
|
WiFi.setAutoReconnect(true);
|
|
|
|
WiFi.persistent(true);
|
|
|
|
|
2020-10-25 20:35:34 +01:00
|
|
|
Debugln();
|
2021-03-14 21:58:35 +01:00
|
|
|
DebugT(F("Connected to " )); Debugln(WiFi.SSID());
|
|
|
|
DebugT(F("IP address: " )); Debugln(WiFi.localIP());
|
|
|
|
DebugT(F("IP gateway: " )); Debugln(WiFi.gatewayIP());
|
2020-10-25 20:35:34 +01:00
|
|
|
Debugln();
|
|
|
|
|
|
|
|
httpUpdater.setup(&httpServer);
|
|
|
|
httpUpdater.setIndexPage(UpdateServerIndex);
|
|
|
|
httpUpdater.setSuccessPage(UpdateServerSuccess);
|
|
|
|
DebugTf(" took [%d] seconds => OK!\r\n", (millis() - lTime) / 1000);
|
|
|
|
|
|
|
|
} // startWiFi()
|
|
|
|
|
|
|
|
//===========================================================================================
|
|
|
|
void startTelnet()
|
|
|
|
{
|
2021-10-24 10:53:18 +02:00
|
|
|
OTGWSerial.print(F("\r\nUse 'telnet "));
|
2021-02-19 01:48:31 +01:00
|
|
|
OTGWSerial.print(WiFi.localIP());
|
2021-10-24 10:53:18 +02:00
|
|
|
OTGWSerial.println(F("' for debugging"));
|
2020-10-25 20:35:34 +01:00
|
|
|
TelnetStream.begin();
|
|
|
|
DebugTln(F("\nTelnet server started .."));
|
|
|
|
TelnetStream.flush();
|
|
|
|
} // startTelnet()
|
|
|
|
|
|
|
|
//=======================================================================
|
2021-03-06 16:42:57 +01:00
|
|
|
void startMDNS(const char *hostname)
|
2020-10-25 20:35:34 +01:00
|
|
|
{
|
2021-03-06 16:42:57 +01:00
|
|
|
DebugTf("mDNS setup as [%s.local]\r\n", hostname);
|
|
|
|
if (MDNS.begin(hostname)) // Start the mDNS responder for Hostname.local
|
2020-10-25 20:35:34 +01:00
|
|
|
{
|
2021-03-06 16:42:57 +01:00
|
|
|
DebugTf("mDNS responder started as [%s.local]\r\n", hostname);
|
2020-10-25 20:35:34 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-03-06 16:42:57 +01:00
|
|
|
DebugTln(F("Error setting up MDNS responder!\r\n"));
|
2020-10-25 20:35:34 +01:00
|
|
|
}
|
|
|
|
MDNS.addService("http", "tcp", 80);
|
|
|
|
} // startMDNS()
|
|
|
|
|
2021-03-06 20:26:48 +01:00
|
|
|
void startLLMNR(const char *hostname)
|
2021-03-06 16:42:57 +01:00
|
|
|
{
|
|
|
|
DebugTf("LLMNR setup as [%s]\r\n", hostname);
|
|
|
|
if (LLMNR.begin(hostname)) // Start the LLMNR responder for hostname
|
|
|
|
{
|
|
|
|
DebugTf("LLMNR responder started as [%s]\r\n", hostname);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DebugTln(F("Error setting up LLMNR responder!\r\n"));
|
|
|
|
}
|
|
|
|
} // startLLMNR()
|
|
|
|
|
|
|
|
|
2021-10-16 20:36:00 +02:00
|
|
|
//====[ startNTP ]===
|
|
|
|
void startNTP(){
|
|
|
|
// Initialisation ezTime
|
|
|
|
if (!settingNTPenable) return;
|
|
|
|
if (settingNTPtimezone.length()==0) settingNTPtimezone = NTP_DEFAULT_TIMEZONE; //set back to default timezone
|
|
|
|
if (settingNTPhostname.length()==0) settingNTPhostname = NTP_HOST_DEFAULT; //set back to default timezone
|
|
|
|
|
|
|
|
//void configTime(int timezone_sec, int daylightOffset_sec, const char* server1, const char* server2, const char* server3)
|
|
|
|
configTime(0, 0, CSTR(settingNTPhostname), nullptr, nullptr);
|
|
|
|
NtpStatus = TIME_WAITFORSYNC;
|
|
|
|
}
|
|
|
|
|
|
|
|
void loopNTP(){
|
|
|
|
if (!settingNTPenable) return;
|
|
|
|
switch (NtpStatus){
|
|
|
|
case TIME_NOTSET:
|
|
|
|
case TIME_NEEDSYNC:
|
|
|
|
NtpLastSync = time(nullptr); //remember last sync
|
2021-10-23 21:18:41 +02:00
|
|
|
DebugTln(F("Start time syncing"));
|
2021-10-16 20:36:00 +02:00
|
|
|
startNTP();
|
|
|
|
NtpStatus = TIME_WAITFORSYNC;
|
|
|
|
break;
|
|
|
|
case TIME_WAITFORSYNC:
|
|
|
|
if ((time(nullptr)>0) || (time(nullptr) >= NtpLastSync)) {
|
|
|
|
NtpLastSync = time(nullptr); //remember last sync
|
2021-10-16 21:46:10 +02:00
|
|
|
|
2021-10-19 20:52:13 +02:00
|
|
|
DebugTf("Timezone lookup for [%s]\r\n", CSTR(settingNTPtimezone));
|
2021-10-16 20:36:00 +02:00
|
|
|
auto myTz = manager.createForZoneName(CSTR(settingNTPtimezone));
|
2021-10-19 20:52:13 +02:00
|
|
|
|
2021-10-16 21:46:10 +02:00
|
|
|
if (myTz.isError()){
|
2021-10-19 20:52:13 +02:00
|
|
|
DebugTf("Error: Timezone Invalid/Not Found: [%s]\r\n", CSTR(settingNTPtimezone));
|
2021-10-16 21:46:10 +02:00
|
|
|
settingNTPtimezone = NTP_DEFAULT_TIMEZONE;
|
|
|
|
myTz = manager.createForZoneName(CSTR(settingNTPtimezone)); //try with default Timezone instead
|
2021-10-23 21:18:41 +02:00
|
|
|
} else DebugTln(F("Timezone lookup: successful"));
|
2021-10-16 21:46:10 +02:00
|
|
|
|
2021-10-16 20:36:00 +02:00
|
|
|
auto myTime = ZonedDateTime::forUnixSeconds(NtpLastSync, myTz);
|
|
|
|
setTime(myTime.hour(), myTime.minute(), myTime.second(), myTime.day(), myTime.month(), myTime.year());
|
|
|
|
NtpStatus = TIME_SYNC;
|
2021-10-23 21:18:41 +02:00
|
|
|
DebugTln(F("Time synced!"));
|
2021-10-16 20:36:00 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TIME_SYNC:
|
|
|
|
if ((time(nullptr)-NtpLastSync) > NTP_RESYNC_TIME){
|
|
|
|
//when xx seconds have passed, resync using NTP
|
2021-10-23 21:18:41 +02:00
|
|
|
DebugTln(F("Time resync needed"));
|
2021-10-16 20:36:00 +02:00
|
|
|
NtpStatus = TIME_NEEDSYNC;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DECLARE_TIMER_SEC(timerNTPtime, 10, CATCH_UP_MISSED_TICKS);
|
2021-11-06 16:02:32 +01:00
|
|
|
if DUE(timerNTPtime) DebugTf("Epoch Seconds: %d\r\n", time(nullptr)); //timeout, then break out of this loop
|
2021-10-16 20:36:00 +02:00
|
|
|
}
|
|
|
|
|
2021-02-24 22:57:37 +01:00
|
|
|
String getMacAddress() {
|
|
|
|
uint8_t baseMac[6];
|
|
|
|
char baseMacChr[13] = {0};
|
|
|
|
# if defined(ESP8266)
|
|
|
|
WiFi.macAddress(baseMac);
|
|
|
|
sprintf(baseMacChr, "%02X%02X%02X%02X%02X%02X", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
|
|
|
|
# elif defined(ESP32)
|
|
|
|
esp_read_mac(baseMac, ESP_MAC_WIFI_STA);
|
|
|
|
sprintf(baseMacChr, "%02X%02X%02X%02X%02X%02X", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
|
|
|
|
# else
|
|
|
|
sprintf(baseMacChr, "%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
|
|
|
# endif
|
|
|
|
return String(baseMacChr);
|
|
|
|
}
|
|
|
|
|
2021-02-28 15:44:53 +01:00
|
|
|
String getUniqueId() {
|
|
|
|
String uniqueId = "otgw-"+(String)getMacAddress();
|
2021-02-24 22:57:37 +01:00
|
|
|
return String(uniqueId);
|
|
|
|
}
|
|
|
|
|
2021-02-14 19:26:37 +01:00
|
|
|
|
2020-10-25 20:35:34 +01:00
|
|
|
/***************************************************************************
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
|
|
* persons to whom the Software is furnished to do so, subject to the
|
|
|
|
* following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included
|
|
|
|
* in all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
|
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
|
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
|
|
|
|
* OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
|
|
|
|
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*
|
|
|
|
****************************************************************************
|
|
|
|
*/
|