diff --git a/lib/AsyncTCP/src/AsyncTCP.cpp b/lib/AsyncTCP/src/AsyncTCP.cpp index 89ff6ee..df4a7c1 100644 --- a/lib/AsyncTCP/src/AsyncTCP.cpp +++ b/lib/AsyncTCP/src/AsyncTCP.cpp @@ -156,6 +156,7 @@ static void _handle_async_event(lwip_event_packet_t * e){ // do nothing when arg is NULL //ets_printf("event arg == NULL: 0x%08x\n", e->recv.pcb); } else if(e->event == LWIP_TCP_CLEAR){ +// ets_printf("-X: 0x%08x\n", e->recv.pcb); _remove_events_with_arg(e->arg); } else if(e->event == LWIP_TCP_RECV){ //ets_printf("-R: 0x%08x\n", e->recv.pcb); @@ -374,6 +375,10 @@ typedef struct { static err_t _tcp_output_api(struct tcpip_api_call_data *api_call_msg){ tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; msg->err = ERR_CONN; + if(msg->closed_slot >= 16 || msg->closed_slot < -1) { + Serial.printf("CLOSED SLOTS BOUNDS!! _tcp_output_api (%d)\r\n", msg->closed_slot); + return msg->err; + } if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) { msg->err = tcp_output(msg->pcb); } @@ -394,6 +399,10 @@ static esp_err_t _tcp_output(tcp_pcb * pcb, int8_t closed_slot) { static err_t _tcp_write_api(struct tcpip_api_call_data *api_call_msg){ tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; msg->err = ERR_CONN; + if(msg->closed_slot >= 16 || msg->closed_slot < -1) { + Serial.printf("CLOSED SLOTS BOUNDS!! _tcp_write_api (%d)\r\n", msg->closed_slot); + return msg->err; + } if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) { msg->err = tcp_write(msg->pcb, msg->write.data, msg->write.size, msg->write.apiflags); } @@ -417,6 +426,10 @@ static esp_err_t _tcp_write(tcp_pcb * pcb, int8_t closed_slot, const char* data, static err_t _tcp_recved_api(struct tcpip_api_call_data *api_call_msg){ tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; msg->err = ERR_CONN; + if(msg->closed_slot >= 16 || msg->closed_slot < -1) { + Serial.printf("CLOSED SLOTS BOUNDS!! _tcp_recv_api (%d)\r\n", msg->closed_slot); + return msg->err; + } if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) { msg->err = 0; tcp_recved(msg->pcb, msg->received); @@ -439,6 +452,10 @@ static esp_err_t _tcp_recved(tcp_pcb * pcb, int8_t closed_slot, size_t len) { static err_t _tcp_close_api(struct tcpip_api_call_data *api_call_msg){ tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; msg->err = ERR_CONN; + if(msg->closed_slot >= 16 || msg->closed_slot < -1) { + Serial.printf("CLOSED SLOTS BOUNDS!! _tcp_close_api (%d)\r\n", msg->closed_slot); + return msg->err; + } if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) { msg->err = tcp_close(msg->pcb); } @@ -459,6 +476,10 @@ static esp_err_t _tcp_close(tcp_pcb * pcb, int8_t closed_slot) { static err_t _tcp_abort_api(struct tcpip_api_call_data *api_call_msg){ tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; msg->err = ERR_CONN; + if(msg->closed_slot >= 16 || msg->closed_slot < -1) { + Serial.printf("CLOSED SLOTS BOUNDS!! _tcp_abort_api (%d)\r\n", msg->closed_slot); + return msg->err; + } if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) { tcp_abort(msg->pcb); } @@ -834,6 +855,10 @@ void AsyncClient::_allocate_closed_slot(){ } void AsyncClient::_free_closed_slot(){ + if(_closed_slot >= 16 || _closed_slot < -1) { + Serial.printf("CLOSED SLOTS BOUNDS!! free_closed_slot (%d)\r\n", _closed_slot); + return; + } if (_closed_slot != -1) { _closed_slots[_closed_slot] = _closed_index; _closed_slot = -1; diff --git a/lib/esp32FOTA/src/esp32fota.cpp b/lib/esp32FOTA/src/esp32fota.cpp index df60660..5e25ea6 100644 --- a/lib/esp32FOTA/src/esp32fota.cpp +++ b/lib/esp32FOTA/src/esp32fota.cpp @@ -11,6 +11,7 @@ #include #include #include "../../ArduinoJson/ArduinoJson.h" +#include "../../asyncHTTPrequest/src/asyncHTTPrequest.h" extern void forceBootInit(); @@ -328,3 +329,237 @@ void esp32FOTA::onFail( std::function func ) { _onFail = func; } + + + + + + + + + + + + + + + +void FOTAconnectCallback(void* arg, AsyncClient * c) +{ + esp32FOTA* pInstance = (esp32FOTA*)arg; + if(pInstance) { + Serial.printf("ESPFOTA Connected. Sending Data\r\n"); + String resp; + + resp = "GET "; + resp += pInstance->getURI(); + resp += " HTTP/1.1\r\n" + + "Host: "; + resp += pInstance->getHost(); + resp += "\r\n" +// "www.mrjones.id.au" "\r\n" + "Connection: close\r\n\r\n"; + +/* c->write(("GET " + pInstance->getURI() + " HTTP/1.1\r\n" + "Host: " + pInstance->getHost() + "\r\n" +// "www.mrjones.id.au" "\r\n" + "Connection: close\r\n\r\n") + .c_str());*/ + c->write(resp.c_str()); + } +} + +void FOTAdataCallback(void* arg, AsyncClient* c, void* data, size_t len) +{ + esp32FOTA* pInstance = (esp32FOTA*)arg; + if(pInstance == NULL) { + c->close(); + return; + } + + Serial.printf("FOTA received with length: %d\r\n", len); + + char JSONMessage[1500]; + memset(JSONMessage, 0, 1500); + char* pData = (char*)data; + for (int i = 0; i < len && i < 1499; i++) { + JSONMessage[i] = pData[i]; + } + + Serial.printf("%s\r\n", JSONMessage); + + pInstance->decodeResponse(JSONMessage); + + c->close(); +} + +bool esp32FOTA::decodeResponse(String payload) +{ + int str_len = payload.length() + 1; + char* JSONMessage = new char[str_len]; + payload.toCharArray(JSONMessage, str_len); + + bool retval = decodeResponse(JSONMessage); + + delete[] JSONMessage; + + return retval; +} + +bool esp32FOTA::decodeResponse(char* resp) +{ + StaticJsonBuffer<300> JSONBuffer; //Memory pool + JsonObject &parsed = JSONBuffer.parseObject(resp); //Parse message + + if (!parsed.success()) + { //Check for errors in parsing +// delete[] JSONMessage; + Serial.println("FOTA Parsing failed\r\n"); + // delay(5000); + // return false; + } + + const char *pltype = parsed["type"]; + int plversion = parsed["version"]; + const char *plhost = parsed["host"]; + _port = parsed["port"]; + const char *plbin = parsed["bin"]; + + String jshost(plhost); + String jsbin(plbin); + + _host = jshost; + _bin = jsbin; + + String fwtype(pltype); + + if (plversion > _firwmareVersion && fwtype == _firwmareType) + { + _newVersion = plversion; + return true; + } + else + { + _newVersion = 0; + return false; + } +} + + +bool esp32FOTA::setURL(const char* URL, const char* expectedProtocol) +{ + String url(URL); + + // check for : (http: or https: + int index = url.indexOf(':'); + if(index < 0) { + log_e("failed to parse protocol"); + return false; + } + + _webprotocol = url.substring(0, index); + if (_webprotocol != expectedProtocol) { + log_w("unexpected protocol: %s, expected %s", _protocol.c_str(), expectedProtocol); + return false; + } + + url.remove(0, (index + 3)); // remove http:// or https:// + + index = url.indexOf('/'); + String host = url.substring(0, index); + url.remove(0, index); // remove host part + +/* // get Authorization + index = host.indexOf('@'); + if(index >= 0) { + // auth info + String auth = host.substring(0, index); + host.remove(0, index + 1); // remove auth part including @ + _base64Authorization = base64::encode(auth); + }*/ + + // get port + _webport = 80; + index = host.indexOf(':'); + if(index >= 0) { + _webhost = host.substring(0, index); // hostname + host.remove(0, (index + 1)); // remove hostname + : + _webport = host.toInt(); // get port + } else { + _webhost = host; + } + + _webURI = url; + log_d("host: %s port: %d url: %s", _webhost.c_str(), _webport, _webURI.c_str()); + Serial.printf("host: %s port: %d url: %s", _webhost.c_str(), _webport, _webURI.c_str()); + return true; +} + +/*void esp32FOTA::setupAsync(const char* host) +{ + setURL(host, "http"); + + static const char* shost = host; + _webclient.onError([](void* arg, AsyncClient * c, int8_t error) { + Serial.printf("ESPFOTA Error %s\r\n", c->errorToString(error)); + c->close(); + }); + _webclient.onTimeout([](void* arg, AsyncClient * c, uint32_t tm) { + Serial.printf("ESPFOTA Timeout\r\n"); + }); +// _webclient.onConnect([](void* arg, AsyncClient * c) { +// Serial.printf("ESPFOTA Connected. Sending Data\r\n"); +// c->write(("GET /?format=json HTTP/1.1\r\n" +// "Host: " + +// String(shost) + "\r\n" +// "Connection: close\r\n\r\n") +// .c_str()); +// }); + // _webclient.onData([](void* arg, AsyncClient* c, void* data, size_t len) { + // Serial.printf("FOTA received with length: %d\r\n", len); + // Serial.printf("%s\r\n", (char*)data); + // c->close(); + // }); + _webclient.onConnect(FOTAconnectCallback, this); + _webclient.onData(FOTAdataCallback, this); +}*/ + +// void esp32FOTA::poll(const char* host) +// { +// _webclient.connect(host, 80); +// } + + +asyncHTTPrequest request; + +void FOTArequestCB(void* optParm, asyncHTTPrequest* pRequest, int readyState){ + if(readyState == 4){ // resposnse + String JSONinfo(pRequest->responseText()); + Serial.println(JSONinfo); + Serial.println(); +// pRequest->close(); + esp32FOTA* pFOTA = (esp32FOTA*) optParm; + if(pFOTA) pFOTA->decodeResponse(JSONinfo); +// delete pRequest; + } + if(readyState == 1) { // connected + pRequest->send(); + } +} + +void esp32FOTA::setupAsync(const char* host) +{ + request.setDebug(true); + request.onReadyStateChange(FOTArequestCB, this); +} + +void esp32FOTA::poll(const char* host) +{ + asyncHTTPrequest* pRequest = &request/*new asyncHTTPrequest*/; + // pRequest->setDebug(true); + // pRequest->onReadyStateChange(FOTArequestCB, this); + if(pRequest->readyState() == 0 || pRequest->readyState() == 4) { + bool bOK = pRequest->open("GET", host); + } +} diff --git a/lib/esp32FOTA/src/esp32fota.h b/lib/esp32FOTA/src/esp32fota.h index 589fb89..fafdd46 100644 --- a/lib/esp32FOTA/src/esp32fota.h +++ b/lib/esp32FOTA/src/esp32fota.h @@ -10,6 +10,8 @@ //#include #include +#include "../../AsyncTCP/src/AsyncTCP.h" +#include "../../asyncHTTPrequest/src/asyncHTTPrequest.h" class esp32FOTA { @@ -24,6 +26,16 @@ public: void onSuccess( std::function func ); void onFail( std::function func ); int getNewVersion() { return _newVersion; }; + + bool setURL(const char* URL, const char* expectedProtocol); + void setupAsync(const char* host); + void poll(const char* host); + bool decodeResponse(String payload); + bool decodeResponse(char* resp); + + const char* getURI() { return _webURI.c_str(); }; + const char* getHost() { return _webhost.c_str(); }; + private: String getHeaderValue(String header, String headerName); String getDeviceID(); @@ -36,6 +48,11 @@ private: std::function _onComplete; std::function _onSuccess; std::function _onFail; + AsyncClient _webclient; + String _webhost; + String _webURI; + String _webprotocol; + int _webport; }; #endif \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index b244765..a163477 100644 --- a/platformio.ini +++ b/platformio.ini @@ -20,12 +20,12 @@ upload_speed = 921600 ;upload_flags = ; --port=3232 upload_port = COM5 -upload_protocol = esptool +;upload_protocol = esptool ;monitor_speed = 115200 extra_scripts = post:add_CRC.py ; replace shitty Arduino millis with a linear time version build_flags = -Wl,--wrap,millis debug_tool = esp-prog -;upload_protocol = esp-prog +upload_protocol = esp-prog debug_init_break = \ No newline at end of file diff --git a/src/Afterburner.cpp b/src/Afterburner.cpp index 07490b4..f718aa5 100644 --- a/src/Afterburner.cpp +++ b/src/Afterburner.cpp @@ -436,13 +436,15 @@ void setup() { sCredentials creds = NVstore.getCredentials(); // local AP credentials - if(NVstore.getUserSettings().enableWifi) { - initWifi(WiFi_TriggerPin, creds.SSID, creds.APpassword); +// if(NVstore.getUserSettings().enableWifi) { + if(NVstore.getUserSettings().wifiMode) { + initWifi(creds.SSID, creds.APpassword); // SSID and passowrd the the ESP32's inbuilt AP #if USE_OTA == 1 if(NVstore.getUserSettings().enableOTA) { initOTA(); } #endif // USE_OTA + initFOTA(); #if USE_WEBSERVER == 1 initWebServer(); #endif // USE_WEBSERVER @@ -1798,7 +1800,8 @@ void doStreaming() { #if USE_WIFI == 1 - if(NVstore.getUserSettings().enableWifi) { +// if(NVstore.getUserSettings().enableWifi) { + if(NVstore.getUserSettings().wifiMode) { doWiFiManager(); #if USE_OTA == 1 DoOTA(); diff --git a/src/Bluetooth/BluetoothHC05.cpp b/src/Bluetooth/BluetoothHC05.cpp index 729a01a..3212eb3 100644 --- a/src/Bluetooth/BluetoothHC05.cpp +++ b/src/Bluetooth/BluetoothHC05.cpp @@ -122,13 +122,13 @@ CBluetoothHC05::begin() else { DebugPort.println("OK"); } - DebugPort.print(" Lowering power consumption..."); +/* DebugPort.print(" Lowering power consumption..."); if(!ATCommand("AT+IPSCAN=1024,1,1024,1\r\n")) { DebugPort.println("FAILED"); } else { DebugPort.println("OK"); - } + }*/ DebugPort.print(" Getting MAC address..."); int len = 32; char response[32]; diff --git a/src/OLED/WiFiScreen.cpp b/src/OLED/WiFiScreen.cpp index 18753c9..fde8f2a 100644 --- a/src/OLED/WiFiScreen.cpp +++ b/src/OLED/WiFiScreen.cpp @@ -61,7 +61,7 @@ CWiFiScreen::_initUI() _OTAsel = NVstore.getUserSettings().enableOTA; _bShowMAC = false; - if(NVstore.getUserSettings().enableWifi) { + if(NVstore.getUserSettings().wifiMode) { if(isWifiAP()) { if(isWifiConfigPortal()) { _colSel = 1; // " WiFi: CFG AP only " diff --git a/src/Utility/NVStorage.cpp b/src/Utility/NVStorage.cpp index 3051b41..b2ceef4 100644 --- a/src/Utility/NVStorage.cpp +++ b/src/Utility/NVStorage.cpp @@ -381,7 +381,8 @@ sUserSettings::load() DebugPort.printf("2) Window = %f\r\n", ThermostatWindow); validatedLoad("frostOn", FrostOn, 0, u8inBounds, 0, 10); validatedLoad("frostRise", FrostRise, 5, u8inBounds, 0, 20); - validatedLoad("enableWifi", enableWifi, 1, u8inBounds, 0, 1); +// validatedLoad("enableWifi", enableWifi, 1, u8inBounds, 0, 1); + validatedLoad("enableWifi", wifiMode, 1, u8inBounds, 0, 3); validatedLoad("enableOTA", enableOTA, 0, u8inBounds, 0, 1); validatedLoad("cyclicStop", cyclic.Stop, 0, s8inBounds, 0, 10); validatedLoad("cyclicStart", cyclic.Start, -1, s8inBounds, -20, 0); @@ -448,7 +449,8 @@ sUserSettings::save() preferences.putFloat("thermoWindow", ThermostatWindow); preferences.putUChar("frostOn", FrostOn); preferences.putUChar("frostRise", FrostRise); - preferences.putUChar("enableWifi", enableWifi); +// preferences.putUChar("enableWifi", enableWifi); + preferences.putUChar("enableWifi", wifiMode); preferences.putUChar("enableOTA", enableOTA); preferences.putChar("cyclicStop", cyclic.Stop); preferences.putChar("cyclicStart",cyclic.Start); diff --git a/src/Utility/NVStorage.h b/src/Utility/NVStorage.h index c7ef53e..3ca5e8e 100644 --- a/src/Utility/NVStorage.h +++ b/src/Utility/NVStorage.h @@ -287,8 +287,9 @@ struct sUserSettings : public CESP32_NVStorage { uint8_t FrostOn; uint8_t FrostRise; uint8_t useThermostat; - uint8_t enableWifi; +// uint8_t enableWifi; uint8_t enableOTA; + uint8_t wifiMode; uint16_t FrameRate; sCyclicThermostat cyclic; sHomeMenuActions HomeMenu; @@ -307,7 +308,8 @@ struct sUserSettings : public CESP32_NVStorage { retval &= ThermostatMethod <= 3; // only modes 0, 1 or 2, 3 retval &= INBOUNDS(ThermostatWindow, 0.2f, 10.f); retval &= useThermostat < 2; - retval &= (enableWifi == 0) || (enableWifi == 1); +// retval &= (enableWifi == 0) || (enableWifi == 1); + retval &= INBOUNDS(wifiMode, 0, 3); retval &= (enableOTA == 0) || (enableOTA == 1); retval &= GPIO.in1Mode < 4; retval &= GPIO.in2Mode < 3; @@ -329,7 +331,8 @@ struct sUserSettings : public CESP32_NVStorage { FrostOn = 0; FrostRise = 5; useThermostat = 1; - enableWifi = 1; +// enableWifi = 1; + wifiMode = 1; enableOTA = 0; GPIO.in1Mode = CGPIOin1::Disabled; GPIO.in2Mode = CGPIOin2::Disabled; @@ -358,7 +361,8 @@ struct sUserSettings : public CESP32_NVStorage { FrostOn = rhs.FrostOn; FrostRise = rhs.FrostRise; useThermostat = rhs.useThermostat; - enableWifi = rhs.enableWifi; +// enableWifi = rhs.enableWifi; + wifiMode = rhs.wifiMode; enableOTA = rhs.enableOTA; GPIO.in1Mode = rhs.GPIO.in1Mode; GPIO.in2Mode = rhs.GPIO.in2Mode; diff --git a/src/WiFi/ABMqtt.cpp b/src/WiFi/ABMqtt.cpp index ea23c0b..db06993 100644 --- a/src/WiFi/ABMqtt.cpp +++ b/src/WiFi/ABMqtt.cpp @@ -24,6 +24,9 @@ #if USE_MQTT == 1 +//#define BLOCK_MQTT_RECON + + #include #include "ABMqtt.h" #include "../../lib/async-mqtt-client/src/AsyncMqttClient.h" @@ -189,8 +192,10 @@ void onMqttSubscribe(uint16_t packetId, uint8_t qos) { bool mqttInit() { #ifdef USE_RTOS_MQTTTIMER +#ifndef BLOCK_MQTT_RECON if(mqttReconnectTimer==NULL) - mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(20000), pdFALSE, (void*)0, reinterpret_cast(connectToMqtt)); + mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(6000), pdFALSE, (void*)0, reinterpret_cast(connectToMqtt)); +#endif #else mqttReconnect = 0; #endif @@ -282,9 +287,11 @@ void doMQTT() #endif #ifdef USE_RTOS_MQTTTIMER +#ifndef BLOCK_MQTT_RECON if (!MQTTclient.connected() && WiFi.isConnected() && !xTimerIsTimerActive(mqttReconnectTimer)) { - xTimerStart(mqttReconnectTimer, 0); + xTimerStart(mqttReconnectTimer, 0); } +#endif #else if (!MQTTclient.connected() && WiFi.isConnected() && mqttReconnect==0) { mqttReconnect = millis() + 5000; diff --git a/src/WiFi/BTCWifi.cpp b/src/WiFi/BTCWifi.cpp index 920de4c..6ae73e7 100644 --- a/src/WiFi/BTCWifi.cpp +++ b/src/WiFi/BTCWifi.cpp @@ -30,8 +30,6 @@ #include "../Utility/NVStorage.h" #include "../../lib/WiFiManager-dev/WiFiManager.h" -//#define USE_AP - // function to control the behaviour upon reboot if no wifi manager credentials exist // or connection fails void prepBootIntoConfigPortal(bool state); @@ -43,7 +41,6 @@ WiFiManager wm; bool isPortalAP = false; // true if config portal is running bool isSTA = false; // true if connected to an access point -int TRIG_PIN; // pin that triggers the configuration portal when set to LOW unsigned restartServer = 0; // set to time of portal reconfig - will cause reboot a while later char MACstr[2][20]; // MACstr[0] STA, MACstr[1] = AP int wifiButtonState = 0; @@ -52,12 +49,9 @@ unsigned long WifiReconnectHoldoff = 0; extern CScreenManager ScreenManager; -bool initWifi(int initpin,const char *failedssid, const char *failedpassword) +bool initWifi(const char *failedssid, const char *failedpassword) { - TRIG_PIN = initpin; - pinMode(TRIG_PIN, INPUT_PULLUP); - // report the MAC addresses - note individual values for STA and AP modes uint8_t MAC[6]; esp_read_mac(MAC, ESP_MAC_WIFI_STA); @@ -121,8 +115,10 @@ bool initWifi(int initpin,const char *failedssid, const char *failedpassword) DebugPort.println("Now promoting to STA+AP mode..."); retval = true; } -#ifdef USE_AP - startAP = true; +#if USE_AP_ALWAYS == 1 + if(NVstore.getUserSettings().wifiMode & 0x01) { // Own AP enabled + startAP = true; + } #endif if(startAP) { // for STA+AP mode we *must* use the same RF channel as STA @@ -149,7 +145,7 @@ bool initWifi(int initpin,const char *failedssid, const char *failedpassword) // call from main sketch loop() void doWiFiManager() { - if(NVstore.getUserSettings().enableWifi) { + if(NVstore.getUserSettings().wifiMode) { wm.process(); if(WiFi.status() != WL_CONNECTED) { @@ -177,60 +173,14 @@ void doWiFiManager() WifiReconnectHoldoff = 0; } -#if USE_PORTAL_TRIGGER_PIN == 1 - // manage handling of pin to enter WiFManager config portal - // we typically use the BOOT pin for this (pins.h) - // - // Quick Press (< 1 sec) - enable config portal - // > 1 second (< 5 sec) press - disable config portal - // > 5 second press - erase credentials, enable config portal - static bool pinDown = false; - static long pinTime = 0; - unsigned long tDelta; - - if(digitalRead(TRIG_PIN) == LOW) { - if(!pinDown) { - pinTime = millis(); - ScreenManager.reqUpdate(); - } - pinDown = true; - // track hold duration - change OLED Wifi annotation according to length of press - tDelta = millis() - pinTime; - if(tDelta > 5000) - wifiButtonState = 3; // we will show 'ERS' on OLED! - else if(tDelta > 1000) - wifiButtonState = 2; // we will show 'HTR' on OLED! - else - wifiButtonState = 1; // we will show 'CFG' on OLED! - } - else { - if(pinDown) { - pinDown = false; - tDelta = millis() - pinTime; - DebugPort.printf("Wifi config button tDelta = %ld\r\n", tDelta); - // > 5 second press? - if(tDelta > 5000) { - wifiEnterConfigPortal(true, true); // very long press - clear credentials, reboot into portal - } - // > 1 second press? - else if(tDelta > 1000) { - wifiEnterConfigPortal(false); // long press - reboot into web server - } - // > 50ms press? - else if(tDelta > 50) { - wifiEnterConfigPortal(true); // quick press - reboot into portal - } - // consider as contact bounce if < 50ms! - } - } -#endif } } void wifiDisable(long rebootDelay) { sUserSettings settings = NVstore.getUserSettings(); - settings.enableWifi = 0; +// settings.enableWifi = 0; + settings.wifiMode = 0; NVstore.setUserSettings(settings); NVstore.save(); @@ -249,7 +199,7 @@ void wifiEnterConfigPortal(bool state, bool erase, long rebootDelay) wm.disconnect(); sUserSettings settings = NVstore.getUserSettings(); - settings.enableWifi = 1; + settings.wifiMode = 1; NVstore.setUserSettings(settings); NVstore.save(); @@ -286,7 +236,8 @@ void wifiFactoryDefault() wm.resetSettings(); prepBootIntoConfigPortal(false); sUserSettings settings = NVstore.getUserSettings(); - settings.enableWifi = 1; +// settings.enableWifi = 1; + settings.wifiMode = 1; NVstore.setUserSettings(settings); NVstore.save(); } @@ -305,7 +256,7 @@ void APstartedCallback(WiFiManager*) const char* getWifiAPAddrStr() { - if(NVstore.getUserSettings().enableWifi) { + if(NVstore.getUserSettings().wifiMode) { IPAddress IPaddr = WiFi.softAPIP(); // use stepping stone - function returns an automatic stack var - LAME! static char APIPaddr[16]; sprintf(APIPaddr, "%d.%d.%d.%d", IPaddr[0], IPaddr[1], IPaddr[2], IPaddr[3]); @@ -317,7 +268,7 @@ const char* getWifiAPAddrStr() const char* getWifiSTAAddrStr() { - if(NVstore.getUserSettings().enableWifi) { + if(NVstore.getUserSettings().wifiMode) { IPAddress IPaddr = WiFi.localIP(); // use stepping stone - function returns an automatic stack var - LAME! static char STAIPaddr[16]; sprintf(STAIPaddr, "%d.%d.%d.%d", IPaddr[0], IPaddr[1], IPaddr[2], IPaddr[3]); @@ -339,7 +290,7 @@ const char* getWifiSTAMACStr() String getSSID() { - if(NVstore.getUserSettings().enableWifi) { + if(NVstore.getUserSettings().wifiMode) { wifi_config_t conf; esp_wifi_get_config(WIFI_IF_STA, &conf); return String(reinterpret_cast(conf.sta.ssid)); @@ -350,7 +301,7 @@ String getSSID() bool isWifiConnected() { - if(NVstore.getUserSettings().enableWifi) + if(NVstore.getUserSettings().wifiMode) return WiFi.status() == WL_CONNECTED; else return false; @@ -358,7 +309,7 @@ bool isWifiConnected() bool isWifiAP() { - if(NVstore.getUserSettings().enableWifi) { + if(NVstore.getUserSettings().wifiMode) { int mode = WiFi.getMode(); return !isSTA && ((mode & WIFI_MODE_AP) != 0); } diff --git a/src/WiFi/BTCWifi.h b/src/WiFi/BTCWifi.h index 493f04b..bff901b 100644 --- a/src/WiFi/BTCWifi.h +++ b/src/WiFi/BTCWifi.h @@ -25,7 +25,7 @@ #include void doWiFiManager(); -bool initWifi(int initpin,const char *failedssid, const char *failedpassword); +bool initWifi(const char *failedssid, const char *failedpassword); const char* getWifiAPAddrStr(); const char* getWifiSTAAddrStr(); const char* getWifiAPMACStr(); diff --git a/src/WiFi/BTCota.cpp b/src/WiFi/BTCota.cpp index 459d19f..85a193f 100644 --- a/src/WiFi/BTCota.cpp +++ b/src/WiFi/BTCota.cpp @@ -51,6 +51,10 @@ void hard_restart() { while(true); } +void initFOTA(){ + FOTA.setupAsync(""); +} + void initOTA(){ ArduinoOTA.setHostname("AfterburnerOTA"); @@ -98,21 +102,25 @@ void initOTA(){ }); ArduinoOTA.begin(); + } +//#define OLD_FOTA + void DoOTA() { ArduinoOTA.handle(); +#ifdef OLD_FOTA // manage Firmware OTA // this is where the controller contacts a web server to discover if new firmware is available // if so, it can download and implant using OTA and become effective next reboot! long tDelta = millis() - FOTAtime; if(tDelta > 0) { -// FOTAtime = millis() + 6000; // 6 seconds + FOTAtime = millis() + 6000; // 6 seconds // FOTAtime = millis() + 60000; // 60 seconds // FOTAtime = millis() + 600000; // 10 minutes - FOTAtime = millis() + 3600000; // 1 hour +// FOTAtime = millis() + 3600000; // 1 hour if ((WiFi.status() == WL_CONNECTED)) { // bug workaround in FOTA where execHTTPcheck does not return false in this condition FOTA.onProgress(onWebProgress); // important - keeps watchdog fed FOTA.onComplete(CheckFirmwareCRC); // upload complete, but not yet verified @@ -137,6 +145,28 @@ void DoOTA() } } } +#else + // manage Firmware OTA + // this is where the controller contacts a web server to discover if new firmware is available + // if so, it can download and implant using OTA and become effective next reboot! + long tDelta = millis() - FOTAtime; + if(tDelta > 0) { +// FOTA.setURL("http://www.mrjones.id.au/afterburner/fota/fota.json", "http"); +// FOTA.setupAsync("http://www.mrjones.id.au/afterburner/fota/fota.json"); + FOTAtime = millis() + 6000; // 6 seconds +// FOTAtime = millis() + 60000; // 60 seconds +// FOTAtime = millis() + 600000; // 10 minutes +// FOTAtime = millis() + 3600000; // 1 hour +// if ((WiFi.status() == WL_CONNECTED)) { // bug workaround in FOTA where execHTTPcheck does not return false in this condition +static bool flipflop = false; + flipflop = !flipflop; + if(flipflop) + FOTA.poll("http://www.mrjones.id.au/afterburner/fota/fotatest.json"); + else + FOTA.poll("http://210.8.241.226/afterburner/fota/fotatest.json"); +// } + } +#endif }; int isUpdateAvailable(bool test) diff --git a/src/WiFi/BTCota.h b/src/WiFi/BTCota.h index 6db92e4..761755a 100644 --- a/src/WiFi/BTCota.h +++ b/src/WiFi/BTCota.h @@ -23,6 +23,7 @@ #define __BTC_OTA_H void initOTA(); +void initFOTA(); void DoOTA(); bool CheckFirmwareCRC(int size); diff --git a/src/cfg/BTCConfig.h b/src/cfg/BTCConfig.h index b60ecb8..9bc94c2 100644 --- a/src/cfg/BTCConfig.h +++ b/src/cfg/BTCConfig.h @@ -23,7 +23,7 @@ // Place Holder Config File - User config vars and defines to be moved here -#define USE_JTAG 0 +#define USE_JTAG 1 ////////////////////////////////////////////////////////////////////////////// // Configure bluetooth options @@ -42,6 +42,7 @@ // HC-05 works OK with WiFi // #define USE_WIFI 1 +#define USE_AP_ALWAYS 1 #define USE_OTA 1 #define USE_WEBSERVER 1 #define USE_MQTT 1 diff --git a/src/cfg/pins.h b/src/cfg/pins.h index 5c8614a..f8e456f 100644 --- a/src/cfg/pins.h +++ b/src/cfg/pins.h @@ -57,5 +57,4 @@ const uint8_t keyCentre_pin = 35; // input only, no chip pullup const uint8_t keyRight_pin = 36; // input only, no chip pullup const uint8_t keyLeft_pin = 39; // input only, no chip pullup -const uint8_t WiFi_TriggerPin = 0; // BOOT switch!