From b5210a79e81a57542c0231e3b4bf5b75de8730b9 Mon Sep 17 00:00:00 2001 From: andreas Date: Fri, 20 Oct 2023 20:40:44 +0200 Subject: [PATCH] allow to change the Wifi AP Ip address and mask --- lib/log/GWLog.cpp | 64 ++++++++++++++++++++++++++++----------------- lib/log/GwLog.h | 4 +++ lib/wifi/GwWifi.cpp | 34 +++++++++++++++++++----- src/main.cpp | 8 ++++++ web/config.json | 16 ++++++++++++ web/index.js | 15 +++++++++++ 6 files changed, 110 insertions(+), 31 deletions(-) diff --git a/lib/log/GWLog.cpp b/lib/log/GWLog.cpp index 65d8236..4ddc8d8 100644 --- a/lib/log/GWLog.cpp +++ b/lib/log/GWLog.cpp @@ -1,23 +1,41 @@ #include "GwLog.h" #include "GwHardware.h" -class DefaultLogWriter: public GwLogWriter{ - public: - virtual ~DefaultLogWriter(){}; - virtual void write(const char *data){ - USBSerial.print(data); - } -}; GwLog::GwLog(int level, GwLogWriter *writer){ logLevel=level; - if (writer == NULL) writer=new DefaultLogWriter(); this->writer=writer; + if (!writer){ + iniBuffer=new char[INIBUFFERSIZE]; + iniBuffer[0]=0; + } locker = xSemaphoreCreateMutex(); } GwLog::~GwLog(){ vSemaphoreDelete(locker); } +void GwLog::writeOut(const char *data) +{ + if (!writer) + { + if (iniBuffer && iniBufferFill < (INIBUFFERSIZE - 1)) + { + size_t remain = INIBUFFERSIZE - iniBufferFill-1; + size_t len = strlen(data); + if (len < remain) + remain = len; + if (remain){ + memcpy(iniBuffer + iniBufferFill, data, remain); + iniBufferFill += remain; + iniBuffer[iniBufferFill] = 0; + } + } + } + else + { + writer->write(data); + } +} void GwLog::logString(const char *fmt,...){ va_list args; va_start(args,fmt); @@ -25,16 +43,12 @@ void GwLog::logString(const char *fmt,...){ recordCounter++; vsnprintf(buffer,bufferSize-1,fmt,args); buffer[bufferSize-1]=0; - if (! writer) { - xSemaphoreGive(locker); - return; - } - writer->write(prefix.c_str()); + writeOut(prefix.c_str()); char buf[20]; snprintf(buf,20,"%lu:",millis()); - writer->write(buf); - writer->write(buffer); - writer->write("\n"); + writeOut(buf); + writeOut(buffer); + writeOut("\n"); xSemaphoreGive(locker); } void GwLog::logDebug(int level,const char *fmt,...){ @@ -48,22 +62,24 @@ void GwLog::logDebug(int level,const char *fmt,va_list args){ recordCounter++; vsnprintf(buffer,bufferSize-1,fmt,args); buffer[bufferSize-1]=0; - if (! writer) { - xSemaphoreGive(locker); - return; - } - writer->write(prefix.c_str()); + writeOut(prefix.c_str()); char buf[20]; snprintf(buf,20,"%lu:",millis()); - writer->write(buf); - writer->write(buffer); - writer->write("\n"); + writeOut(buf); + writeOut(buffer); + writeOut("\n"); xSemaphoreGive(locker); } void GwLog::setWriter(GwLogWriter *writer){ xSemaphoreTake(locker, portMAX_DELAY); if (this->writer) delete this->writer; this->writer=writer; + if (iniBuffer && iniBufferFill){ + writer->write(iniBuffer); + iniBufferFill=0; + delete[] iniBuffer; + iniBuffer=nullptr; + } xSemaphoreGive(locker); } diff --git a/lib/log/GwLog.h b/lib/log/GwLog.h index d4ea76d..4958760 100644 --- a/lib/log/GwLog.h +++ b/lib/log/GwLog.h @@ -16,6 +16,10 @@ class GwLog{ GwLogWriter *writer; SemaphoreHandle_t locker; long long recordCounter=0; + const size_t INIBUFFERSIZE=1024; + char *iniBuffer=nullptr; + size_t iniBufferFill=0; + void writeOut(const char *data); public: static const int LOG=1; static const int ERROR=0; diff --git a/lib/wifi/GwWifi.cpp b/lib/wifi/GwWifi.cpp index 2f6f556..549f99d 100644 --- a/lib/wifi/GwWifi.cpp +++ b/lib/wifi/GwWifi.cpp @@ -11,10 +11,30 @@ GwWifi::GwWifi(const GwConfigHandler *config,GwLog *log, bool fixedApPass){ } void GwWifi::setup(){ LOG_DEBUG(GwLog::LOG,"Wifi setup"); - - IPAddress AP_local_ip(192, 168, 15, 1); // Static address for AP - IPAddress AP_gateway(192, 168, 15, 1); - IPAddress AP_subnet(255, 255, 255, 0); + IPAddress defaultAddr(192,168,15,1); + IPAddress AP_local_ip; // Static address for AP + const String apip=config->getString(config->apIp); + bool cfgIpOk=false; + if (!apip.isEmpty()){ + cfgIpOk= AP_local_ip.fromString(apip); + } + if (! cfgIpOk){ + AP_local_ip=IPAddress(192,168,15,1); + LOG_DEBUG(GwLog::ERROR,"unable to set access point IP %s, falling back to %s", + apip.c_str(),AP_local_ip.toString().c_str()); + } + IPAddress AP_gateway(AP_local_ip); + bool maskOk=false; + IPAddress AP_subnet; + const String apMask=config->getString(config->apMask); + if (!apMask.isEmpty()){ + maskOk=AP_subnet.fromString(apMask); + } + if (! maskOk){ + AP_subnet=IPAddress(255, 255, 255, 0); + LOG_DEBUG(GwLog::ERROR,"unable to set access point mask %s, falling back to %s", + apMask.c_str(),AP_subnet.toString().c_str()); + } WiFi.mode(WIFI_MODE_APSTA); //enable both AP and client const char *ssid=config->getConfigItem(config->systemName)->asCString(); if (fixedApPass){ @@ -33,7 +53,7 @@ void GwWifi::setup(){ lastApAccess=millis(); apShutdownTime=config->getConfigItem(config->stopApTime)->asInt() * 60; if (apShutdownTime < 120 && apShutdownTime != 0) apShutdownTime=120; //min 2 minutes - LOG_DEBUG(GwLog::LOG,"GWWIFI: AP auto shutdown %s (%ds)",apShutdownTime> 0?"enabled":"disabled",apShutdownTime); + LOG_DEBUG(GwLog::ERROR,"GWWIFI: AP auto shutdown %s (%ds)",apShutdownTime> 0?"enabled":"disabled",apShutdownTime); apShutdownTime=apShutdownTime*1000; //ms clientIsConnected=false; connectInternal(); @@ -65,7 +85,7 @@ void GwWifi::loop(){ } else{ if (! clientIsConnected){ - LOG_DEBUG(GwLog::LOG,"client %s now connected",wifiSSID->asCString()); + LOG_DEBUG(GwLog::LOG,"wifiClient %s now connected to",wifiSSID->asCString()); clientIsConnected=true; } } @@ -75,7 +95,7 @@ void GwWifi::loop(){ lastApAccess=millis(); } if ((lastApAccess + apShutdownTime) < millis()){ - LOG_DEBUG(GwLog::LOG,"GWWIFI: shutdown AP"); + LOG_DEBUG(GwLog::ERROR,"GWWIFI: shutdown AP"); WiFi.softAPdisconnect(true); apActive=false; } diff --git a/src/main.cpp b/src/main.cpp index 5d46bf8..aeea06c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -698,6 +698,13 @@ void handleConfigRequestData(AsyncWebServerRequest *request, uint8_t *data, size } TimeMonitor monitor(20,0.2); +class DefaultLogWriter: public GwLogWriter{ + public: + virtual ~DefaultLogWriter(){}; + virtual void write(const char *data){ + USBSerial.print(data); + } +}; void setup() { mainLock=xSemaphoreCreateMutex(); @@ -713,6 +720,7 @@ void setup() { USBSerial.begin(115200); USBSerial.printf("fallback serial enabled\n"); logger.prefix="FALLBACK:"; + logger.setWriter(new DefaultLogWriter()); #endif userCodeHandler.startInitTasks(MIN_USER_TASK); config.stopChanges(); diff --git a/web/config.json b/web/config.json index 126819f..8ad556f 100644 --- a/web/config.json +++ b/web/config.json @@ -119,6 +119,22 @@ "category": "system", "capabilities":{"apPwChange":["true"]} }, + { + "name": "apIp", + "type": "string", + "default":"192.168.15.1", + "check": "checkApIp", + "description": "The IP address for the access point. Clients will get addresses within the same subnet.", + "category":"system" + }, + { + "name": "apMask", + "type": "string", + "default":"255.255.255.0", + "check": "checkNetMask", + "description": "The net mask for the access point", + "category":"system" + }, { "name": "useAdminPass", "type": "boolean", diff --git a/web/index.js b/web/index.js index db31d8d..f1ec95d 100644 --- a/web/index.js +++ b/web/index.js @@ -186,6 +186,21 @@ function checkAdminPass(v){ return checkApPass(v); } +function checkApIp(v,allValues){ + if (! v) return "cannot be empty"; + let err1="must be in the form 192.168.x.x"; + if (! v.match(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/))return err1; + let parts=v.split("."); + if (parts.length != 4) return err1; + for (let idx=0;idx < 4;idx++){ + let iv=parseInt(parts[idx]); + if (iv < 0 || iv > 255) return err1; + } +} +function checkNetMask(v,allValues){ + return checkApIp(v,allValues); +} + function checkIpAddress(v,allValues,def){ if (allValues.tclEnabled != "true") return; if (! v) return "cannot be empty";