diff --git a/bin/build-all.sh b/bin/build-all.sh index dc614cf6..b176df5f 100755 --- a/bin/build-all.sh +++ b/bin/build-all.sh @@ -72,6 +72,9 @@ platformio lib update do_boards "$BOARDS_ESP32" "false" do_boards "$BOARDS_NRF52" "true" +pio run --environment native +cp .pio/build/native/program $OUTDIR/bins/universal/meshtasticd_linux_amd64 + echo "Building SPIFFS for ESP32 targets" pio run --environment tbeam -t buildfs cp .pio/build/tbeam/spiffs.bin $OUTDIR/bins/universal/spiffs-$VERSION.bin @@ -99,7 +102,7 @@ XML echo Generating $ARCHIVEDIR/firmware-$VERSION.zip rm -f $ARCHIVEDIR/firmware-$VERSION.zip -zip --junk-paths $ARCHIVEDIR/firmware-$VERSION.zip $ARCHIVEDIR/spiffs-$VERSION.bin $OUTDIR/bins/universal/firmware-*-$VERSION.* images/system-info.bin bin/device-install.* bin/device-update.* +zip --junk-paths $ARCHIVEDIR/firmware-$VERSION.zip $ARCHIVEDIR/spiffs-$VERSION.bin $OUTDIR/bins/universal/firmware-*-$VERSION.* $OUTDIR/bins/universal/meshtasticd* images/system-info.bin bin/device-install.* bin/device-update.* echo Generating $ARCHIVEDIR/elfs-$VERSION.zip rm -f $ARCHIVEDIR/elfs-$VERSION.zip zip --junk-paths $ARCHIVEDIR/elfs-$VERSION.zip $OUTDIR/elfs/universal/firmware-*-$VERSION.* diff --git a/geeksville-private/TODO.md b/geeksville-private/TODO.md index 1e581150..5ef0d4e4 100644 --- a/geeksville-private/TODO.md +++ b/geeksville-private/TODO.md @@ -2,40 +2,19 @@ You probably don't care about this section - skip to the next one. -* assertion failur -22:57:36 64409 [PositionPlugin] FIXME-update-db Sniffing packet -22:57:36 64409 [PositionPlugin] Delivering rx packet (id=0x5851f437 Fr0xa1 To0xff, WantAck0, HopLim3 Ch0x0 Portnum=3 rxtime=1628895456 priority=10) -22:57:36 64409 [PositionPlugin] Forwarding to phone (id=0x5851f437 Fr0xa1 To0xff, WantAck0, HopLim3 Ch0x0 Portnum=3 rxtime=1628895456 priority=10) -22:57:36 64409 [PositionPlugin] Update DB node 0x85f4da1, rx_time=1628895456 -22:57:36 64409 [PositionPlugin] Plugin routing considered -22:57:36 64409 [PositionPlugin] Add packet record (id=0x5851f437 Fr0xa1 To0xff, WantAck0, HopLim3 Ch0x0 Portnum=3 rxtime=1628895456 priority=10) -22:57:36 64409 [PositionPlugin] Expanding short PSK #1 -22:57:36 64409 [PositionPlugin] Installing AES128 key! -22:57:36 64409 [PositionPlugin] enqueuing for send (id=0x5851f437 Fr0xa1 To0xff, WantAck0, HopLim3 Ch0xb1 encrypted rxtime=1628895456 priority=10) -22:57:36 64409 [PositionPlugin] (bw=125, sf=12, cr=4/8) packet symLen=32 ms, payloadSize=22, time 2596 ms -22:57:36 64409 [PositionPlugin] txGood=6,rxGood=10,rxBad=0 -22:57:36 64409 [PositionPlugin] AirTime - Packet transmitted : 2596ms -22:57:36 64409 [RadioIf] assert failed src/mesh/RadioLibInterface.cpp: 240, void RadioLibInterface::handleReceiveInterrupt(), test=isReceiving - - -add segger systemview documentation - -* USB nrf52 blocks on reads!!! https://github.com/meshtastic/Meshtastic-device/issues/838 -* send debug info 'in-band' -* fix wifi connections for mqtt -* router mode dropping messages? https://meshtastic.discourse.group/t/router-mode-missing-messages/3329/3 -* usb lora dongle from pine64 - -* list portduino on platformio -* figure our wss for mqtt.meshtastic - use cloudflare? 2052 ws, 2053 crypt * measure rak4630 power draw and turn off power for GPS most of the time. We should be able to run on the small solar panel. +* usb lora dongle from pine64, add end user instructions +* turn on watchdog reset if app hangs on nrf52 or esp32 +* pine64 solar boards +* for the matrix gateway? recommended by @sam-uk https://github.com/matrix-org/coap-proxy +* figure our wss for mqtt.meshtastic - use cloudflare? 2052 ws, 2053 crypt * ask for vercel access * finish plan for riot.im * turn on setTx(timeout) and state = setDioIrqParams(SX126X_IRQ_TX_DONE | SX126X_IRQ_TIMEOUT, SX126X_IRQ_TX_DONE | SX126X_IRQ_TIMEOUT); in sx1262 code -* add rak4600 support (with rf95 radio and limited ram) +* NO add rak4600 support (with rf95 radio and limited ram) * store esp32 crashes to flash (and 64KB coredump partition) - https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/core_dump.html -* -* Switch to use https://github.com/adafruit/Adafruit_nRF52_Arduino.git when available (see arduino code for examples) +* If more nodes appear than the nodedb can hold, delete oldest entries from DB +* send debug info 'in-band' * DONE @luxonn reports that after a while the android app stops showing new messages * DONE release android APK - fix recent 1.2.28 crash report * DONE remote admin busted? @@ -48,7 +27,6 @@ add segger systemview documentation * DONE tcp stream problem in python+pordtuino, server thinks client dropped when client DID NOT DROP * DONE TCP mode for android, localhost is at 10.0.2.2 * DONE make sure USB still works in android -* add portduino builds to zip * add license to portduino and make announcement * DONE naks are being dropped (though enqueuedLocal) sometimes before phone/PC gets them * DONE have android fill in if local GPS has poor signal diff --git a/geeksville-private/bl602.md b/geeksville-private/bl602.md new file mode 100644 index 00000000..f4c27500 --- /dev/null +++ b/geeksville-private/bl602.md @@ -0,0 +1,23 @@ + +* nutcracker https://www.pine64.org/2020/10/28/nutcracker-challenge-blob-free-wifi-ble/ +* https://github.com/pine64/bl_iot_sdk +* https://github.com/pine64/bl602-docs / https://pine64.github.io/bl602-docs/ +* https://github.com/pine64/ArduinoCore-bouffalo + + +cd ~/packages +git clone --recursive https://github.com/pine64/bl_iot_sdk + +https://github.com/spacemeowx2/blflash/releases + + +# FIXME or BL604 +cd bl_iot_sdk +export BL60X_SDK_PATH=/home/kevinh/packages/bl_iot_sdk +export CONFIG_CHIP_NAME=BL602 +cd customer_app/bl602_boot2 +make + +* todo run hello world on hardware (check for bl604 vs bl602 first) +* build/run in the crummy arduino environment +* build in platformio \ No newline at end of file diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 8cbff969..dc0f3b95 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -2,6 +2,7 @@ #include "RedirectablePrint.h" #include "RTC.h" #include "concurrency/OSThread.h" +// #include "wifi/WiFiServerAPI.h" #include #include #include @@ -25,6 +26,10 @@ size_t RedirectablePrint::write(uint8_t c) SEGGER_RTT_PutChar(SEGGER_STDOUT_CH, c); #endif + // FIXME - clean this up, the whole relationship of this class to SerialConsole to TCP/bluetooth debug log output is kinda messed up. But for now, just have this hack to + // optionally send chars to TCP also + //WiFiServerPort::debugOut(c); + dest->write(c); return 1; // We always claim one was written, rather than trusting what the // serial port said (which could be zero) diff --git a/src/concurrency/NotifiedWorkerThread.cpp b/src/concurrency/NotifiedWorkerThread.cpp index a7f8fe49..9be2bc90 100644 --- a/src/concurrency/NotifiedWorkerThread.cpp +++ b/src/concurrency/NotifiedWorkerThread.cpp @@ -72,14 +72,21 @@ bool NotifiedWorkerThread::notifyLater(uint32_t delay, uint32_t v, bool overwrit return didIt; } -int32_t NotifiedWorkerThread::runOnce() +void NotifiedWorkerThread::checkNotification() { auto n = notification; - enabled = false; // Only run once per notification notification = 0; // clear notification if (n) { onNotify(n); } +} + + + +int32_t NotifiedWorkerThread::runOnce() +{ + enabled = false; // Only run once per notification + checkNotification(); return RUN_SAME; } diff --git a/src/concurrency/NotifiedWorkerThread.h b/src/concurrency/NotifiedWorkerThread.h index cdb37c35..62827785 100644 --- a/src/concurrency/NotifiedWorkerThread.h +++ b/src/concurrency/NotifiedWorkerThread.h @@ -38,8 +38,14 @@ class NotifiedWorkerThread : public OSThread protected: virtual void onNotify(uint32_t notification) = 0; + /// just calls checkNotification() virtual int32_t runOnce(); + /// Sometimes we might want to check notifications independently of when our thread was getting woken up (i.e. if we are about to change + /// radio transmit/receive modes we want to handle any pending interrupts first). You can call this method and if any notifications are currently + /// pending they will be handled immediately. + void checkNotification(); + private: /** * Notify this thread so it can run diff --git a/src/main.cpp b/src/main.cpp index 3e845e22..a1de8dc6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,9 +25,10 @@ #include // #include +#include "mesh/http/WiFiAPClient.h" + #ifndef NO_ESP32 #include "mesh/http/WebServer.h" -#include "mesh/http/WiFiAPClient.h" #include "nimble/BluetoothUtil.h" #endif @@ -337,9 +338,10 @@ void setup() digitalWrite(RESET_OLED, 1); #endif + bool forceSoftAP = 0; + #ifdef BUTTON_PIN #ifndef NO_ESP32 - bool forceSoftAP = 0; // If the button is connected to GPIO 12, don't enable the ability to use // meshtasticAdmin on the device. @@ -536,10 +538,14 @@ void setup() } #endif -#ifndef NO_ESP32 +#if defined(PORTDUINO) || defined(HAS_WIFI) + mqttInit(); +#endif + // Initialize Wifi initWifi(forceSoftAP); +#ifndef NO_ESP32 // Start web server thread. webServerThread = new WebServerThread(); #endif @@ -548,10 +554,6 @@ void setup() initApiServer(); #endif -#if defined(PORTDUINO) || defined(HAS_WIFI) - mqttInit(); -#endif - // Start airtime logger thread. airTime = new AirTime(); diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h index 90a8c4d1..e818bba5 100644 --- a/src/mesh/PhoneAPI.h +++ b/src/mesh/PhoneAPI.h @@ -81,6 +81,9 @@ class PhoneAPI bool isConnected() { return state != STATE_SEND_NOTHING; } + /// emit a debugging log character, FIXME - implement + void debugOut(char c) { } + protected: /// Our fromradio packet while it is being assembled FromRadio fromRadioScratch; diff --git a/src/mesh/SX1262Interface.cpp b/src/mesh/SX1262Interface.cpp index 8af6d0c1..002050f1 100644 --- a/src/mesh/SX1262Interface.cpp +++ b/src/mesh/SX1262Interface.cpp @@ -146,6 +146,8 @@ void INTERRUPT_ATTR SX1262Interface::disableInterrupt() void SX1262Interface::setStandby() { + checkNotification(); // handle any pending interrupts before we force standby + int err = lora.standby(); assert(err == ERR_NONE); diff --git a/src/mesh/StreamAPI.h b/src/mesh/StreamAPI.h index b33e73ea..58af95b3 100644 --- a/src/mesh/StreamAPI.h +++ b/src/mesh/StreamAPI.h @@ -68,7 +68,7 @@ class StreamAPI : public PhoneAPI, protected concurrency::OSThread void emitRebooted(); virtual void onConnectionChanged(bool connected); - + /// Check the current underlying physical link to see if the client is currently connected virtual bool checkIsConnected() = 0; diff --git a/src/mesh/http/WebServer.cpp b/src/mesh/http/WebServer.cpp index 2633de52..0f3ae5cd 100644 --- a/src/mesh/http/WebServer.cpp +++ b/src/mesh/http/WebServer.cpp @@ -5,7 +5,6 @@ #include #include - #include #include @@ -13,7 +12,6 @@ #include "esp_task_wdt.h" #endif - // Persistant Data Storage #include Preferences prefs; @@ -42,46 +40,41 @@ Preferences prefs; using namespace httpsserver; #include "mesh/http/ContentHandler.h" -SSLCert *cert; -HTTPSServer *secureServer; -HTTPServer *insecureServer; +static SSLCert *cert; +static HTTPSServer *secureServer; +static HTTPServer *insecureServer; +volatile bool isWebServerReady; +volatile bool isCertReady; - - -bool isWebServerReady = 0; -bool isCertReady = 0; - - -void handleWebResponse() +static void handleWebResponse() { - if (isWifiAvailable() == 0) { - return; - } + if (isWifiAvailable()) { - if (isWebServerReady) { - // We're going to handle the DNS responder here so it - // will be ignored by the NRF boards. - handleDNSResponse(); + if (isWebServerReady) { + // We're going to handle the DNS responder here so it + // will be ignored by the NRF boards. + handleDNSResponse(); - secureServer->loop(); - insecureServer->loop(); - } + if(secureServer) + secureServer->loop(); + insecureServer->loop(); + } - /* - Slow down the CPU if we have not received a request within the last few - seconds. - */ - - if (millis() - getTimeSpeedUp() >= (25 * 1000)) { - setCpuFrequencyMhz(80); - setTimeSpeedUp(); + /* + Slow down the CPU if we have not received a request within the last few + seconds. + */ + + if (millis() - getTimeSpeedUp() >= (25 * 1000)) { + setCpuFrequencyMhz(80); + setTimeSpeedUp(); + } } } -void taskCreateCert(void *parameter) +static void taskCreateCert(void *parameter) { - prefs.begin("MeshtasticHTTPS", false); // Delete the saved certs @@ -92,13 +85,32 @@ void taskCreateCert(void *parameter) prefs.remove("cert"); } + DEBUG_MSG("Checking if we have a previously saved SSL Certificate.\n"); + size_t pkLen = prefs.getBytesLength("PK"); size_t certLen = prefs.getBytesLength("cert"); - DEBUG_MSG("Checking if we have a previously saved SSL Certificate.\n"); - if (pkLen && certLen) { DEBUG_MSG("Existing SSL Certificate found!\n"); + + uint8_t *pkBuffer = new uint8_t[pkLen]; + prefs.getBytes("PK", pkBuffer, pkLen); + + uint8_t *certBuffer = new uint8_t[certLen]; + prefs.getBytes("cert", certBuffer, certLen); + + cert = new SSLCert(certBuffer, certLen, pkBuffer, pkLen); + + DEBUG_MSG("Retrieved Private Key: %d Bytes\n", cert->getPKLength()); + // DEBUG_MSG("Retrieved Private Key: " + String(cert->getPKLength()) + " Bytes"); + // for (int i = 0; i < cert->getPKLength(); i++) + // Serial.print(cert->getPKData()[i], HEX); + // Serial.println(); + + DEBUG_MSG("Retrieved Certificate: %d Bytes\n", cert->getCertLength()); + // for (int i = 0; i < cert->getCertLength(); i++) + // Serial.print(cert->getCertData()[i], HEX); + // Serial.println(); } else { DEBUG_MSG("Creating the certificate. This may take a while. Please wait...\n"); yield(); @@ -133,35 +145,35 @@ void taskCreateCert(void *parameter) } } - isCertReady = 1; + isCertReady = true; + + // Must delete self, can't just fall out vTaskDelete(NULL); } void createSSLCert() { + if (isWifiAvailable() && !isCertReady) { - if (isWifiAvailable() == 0) { - return; + // Create a new process just to handle creating the cert. + // This is a workaround for Bug: https://github.com/fhessel/esp32_https_server/issues/48 + // jm@casler.org (Oct 2020) + xTaskCreate(taskCreateCert, /* Task function. */ + "createCert", /* String with name of task. */ + 16384, /* Stack size in bytes. */ + NULL, /* Parameter passed as input of the task */ + 16, /* Priority of the task. */ + NULL); /* Task handle. */ + + DEBUG_MSG("Waiting for SSL Cert to be generated.\n"); + while (!isCertReady) { + DEBUG_MSG("."); + delay(1000); + yield(); + esp_task_wdt_reset(); + } + DEBUG_MSG("SSL Cert Ready!\n"); } - - // Create a new process just to handle creating the cert. - // This is a workaround for Bug: https://github.com/fhessel/esp32_https_server/issues/48 - // jm@casler.org (Oct 2020) - xTaskCreate(taskCreateCert, /* Task function. */ - "createCert", /* String with name of task. */ - 16384, /* Stack size in bytes. */ - NULL, /* Parameter passed as input of the task */ - 16, /* Priority of the task. */ - NULL); /* Task handle. */ - - DEBUG_MSG("Waiting for SSL Cert to be generated.\n"); - while (!isCertReady) { - DEBUG_MSG("."); - delay(1000); - yield(); - esp_task_wdt_reset(); - } - DEBUG_MSG("SSL Cert Ready!\n"); } WebServerThread *webServerThread; @@ -181,6 +193,8 @@ void initWebServer() { DEBUG_MSG("Initializing Web Server ...\n"); +#if 0 +// this seems to be a copypaste dup of taskCreateCert prefs.begin("MeshtasticHTTPS", false); size_t pkLen = prefs.getBytesLength("PK"); @@ -211,6 +225,7 @@ void initWebServer() } else { DEBUG_MSG("Web Server started without SSL keys! How did this happen?\n"); } +#endif // We can now use the new certificate to setup our server as usual. secureServer = new HTTPSServer(cert); @@ -218,14 +233,16 @@ void initWebServer() registerHandlers(insecureServer, secureServer); - DEBUG_MSG("Starting Web Servers...\n"); - secureServer->start(); + if(secureServer) { + DEBUG_MSG("Starting Secure Web Server...\n"); + secureServer->start(); + } + DEBUG_MSG("Starting Insecure Web Server...\n"); insecureServer->start(); - if (secureServer->isRunning() && insecureServer->isRunning()) { - DEBUG_MSG("HTTP and HTTPS Web Servers Ready! :-) \n"); - isWebServerReady = 1; + if (insecureServer->isRunning()) { + DEBUG_MSG("Web Servers Ready! :-) \n"); + isWebServerReady = true; } else { - DEBUG_MSG("HTTP and HTTPS Web Servers Failed! ;-( \n"); + DEBUG_MSG("Web Servers Failed! ;-( \n"); } } - diff --git a/src/mesh/http/WebServer.h b/src/mesh/http/WebServer.h index aacb2e00..74b299dc 100644 --- a/src/mesh/http/WebServer.h +++ b/src/mesh/http/WebServer.h @@ -8,10 +8,6 @@ void initWebServer(); void createSSLCert(); - -void handleWebResponse(); - - class WebServerThread : private concurrency::OSThread { diff --git a/src/mesh/http/WiFiAPClient.cpp b/src/mesh/http/WiFiAPClient.cpp index ed4cd355..4408739d 100644 --- a/src/mesh/http/WiFiAPClient.cpp +++ b/src/mesh/http/WiFiAPClient.cpp @@ -3,6 +3,7 @@ #include "concurrency/Periodic.h" #include "configuration.h" #include "main.h" +#include "mqtt/MQTT.h" #include "mesh/http/WebServer.h" #include "mesh/wifi/WiFiServerAPI.h" #include "target_specific.h" @@ -81,15 +82,6 @@ bool isWifiAvailable() const char *wifiName = radioConfig.preferences.wifi_ssid; - // strcpy(radioConfig.preferences.wifi_ssid, "meshtastic"); - // strcpy(radioConfig.preferences.wifi_password, "meshtastic!"); - - // strcpy(radioConfig.preferences.wifi_ssid, "meshtasticAdmin"); - // strcpy(radioConfig.preferences.wifi_password, "12345678"); - - // radioConfig.preferences.wifi_ap_mode = true; - // radioConfig.preferences.wifi_ap_mode = false; - if (*wifiName) { return true; } else { @@ -118,27 +110,44 @@ void deinitWifi() } } -// Startup WiFi -void initWifi(bool forceSoftAP) +static void onNetworkConnected() { + if (!APStartupComplete) { + // Start web server + DEBUG_MSG("... Starting network services\n"); - if (forceSoftAP) { - // do nothing - // DEBUG_MSG("----- Forcing SoftAP\n"); - } else { - if (isWifiAvailable() == 0) { - return; + // start mdns + if (!MDNS.begin("Meshtastic")) { + DEBUG_MSG("Error setting up MDNS responder!\n"); + } else { + DEBUG_MSG("mDNS responder started\n"); + DEBUG_MSG("mDNS Host: Meshtastic.local\n"); + MDNS.addService("http", "tcp", 80); + MDNS.addService("https", "tcp", 443); } - } + initWebServer(); + initApiServer(); + + APStartupComplete = true; + } + + // FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected' + if(mqtt) + mqtt->reconnect(); +} + +// Startup WiFi +bool initWifi(bool forceSoftAP) +{ forcedSoftAP = forceSoftAP; - createSSLCert(); - - if (radioConfig.has_preferences || forceSoftAP) { + if ((radioConfig.has_preferences && radioConfig.preferences.wifi_ssid[0]) || forceSoftAP) { const char *wifiName = radioConfig.preferences.wifi_ssid; const char *wifiPsw = radioConfig.preferences.wifi_password; + createSSLCert(); + if (!*wifiPsw) // Treat empty password as no password wifiPsw = NULL; @@ -203,21 +212,11 @@ void initWifi(bool forceSoftAP) wifiReconnect = new Periodic("WifiConnect", reconnectWiFi); } } - - if (!MDNS.begin("Meshtastic")) { - DEBUG_MSG("Error setting up MDNS responder!\n"); - - while (1) { - delay(1000); - } - } - DEBUG_MSG("mDNS responder started\n"); - DEBUG_MSG("mDNS Host: Meshtastic.local\n"); - MDNS.addService("http", "tcp", 80); - MDNS.addService("https", "tcp", 443); - - } else + return true; + } else { DEBUG_MSG("Not using WIFI\n"); + return false; + } } // Called by the Espressif SDK to @@ -253,18 +252,7 @@ static void WiFiEvent(WiFiEvent_t event) case SYSTEM_EVENT_STA_GOT_IP: DEBUG_MSG("Obtained IP address: \n"); Serial.println(WiFi.localIP()); - - if (!APStartupComplete) { - // Start web server - DEBUG_MSG("... Starting network services\n"); - initWebServer(); - initApiServer(); - - APStartupComplete = true; - } else { - DEBUG_MSG("... Not starting network services (They're already running)\n"); - } - + onNetworkConnected(); break; case SYSTEM_EVENT_STA_LOST_IP: DEBUG_MSG("Lost IP address and IP address is reset to 0\n"); @@ -284,18 +272,7 @@ static void WiFiEvent(WiFiEvent_t event) case SYSTEM_EVENT_AP_START: DEBUG_MSG("WiFi access point started\n"); Serial.println(WiFi.softAPIP()); - - if (!APStartupComplete) { - // Start web server - DEBUG_MSG("... Starting network services\n"); - initWebServer(); - initApiServer(); - - APStartupComplete = true; - } else { - DEBUG_MSG("... Not starting network services (They're already running)\n"); - } - + onNetworkConnected(); break; case SYSTEM_EVENT_AP_STOP: DEBUG_MSG("WiFi access point stopped\n"); diff --git a/src/mesh/http/WiFiAPClient.h b/src/mesh/http/WiFiAPClient.h index cb27bb4a..acbbdb19 100644 --- a/src/mesh/http/WiFiAPClient.h +++ b/src/mesh/http/WiFiAPClient.h @@ -9,7 +9,9 @@ #include #endif -void initWifi(bool forceSoftAP); +/// @return true if wifi is now in use +bool initWifi(bool forceSoftAP); + void deinitWifi(); bool isWifiAvailable(); diff --git a/src/mesh/wifi/WiFiServerAPI.cpp b/src/mesh/wifi/WiFiServerAPI.cpp index 79c749af..6014f832 100644 --- a/src/mesh/wifi/WiFiServerAPI.cpp +++ b/src/mesh/wifi/WiFiServerAPI.cpp @@ -25,8 +25,6 @@ WiFiServerAPI::~WiFiServerAPI() // FIXME - delete this if the client dropps the connection! } - - /// override close to also shutdown the TCP link void WiFiServerAPI::close() { @@ -51,6 +49,13 @@ int32_t WiFiServerAPI::runOnce() } } +/// If an api server is running, we try to spit out debug 'serial' characters there +void WiFiServerPort::debugOut(char c) +{ + if (apiPort && apiPort->openAPI) + apiPort->openAPI->debugOut(c); +} + #define MESHTASTIC_PORTNUM 4403 WiFiServerPort::WiFiServerPort() : WiFiServer(MESHTASTIC_PORTNUM), concurrency::OSThread("ApiServer") {} diff --git a/src/mesh/wifi/WiFiServerAPI.h b/src/mesh/wifi/WiFiServerAPI.h index c1f9b1be..b7b8c335 100644 --- a/src/mesh/wifi/WiFiServerAPI.h +++ b/src/mesh/wifi/WiFiServerAPI.h @@ -21,8 +21,8 @@ class WiFiServerAPI : public StreamAPI virtual void close(); protected: - - /// We override this method to prevent publishing EVENT_SERIAL_CONNECTED/DISCONNECTED for wifi links (we want the board to stay in the POWERED state to prevent disabling wifi) + /// We override this method to prevent publishing EVENT_SERIAL_CONNECTED/DISCONNECTED for wifi links (we want the board to + /// stay in the POWERED state to prevent disabling wifi) virtual void onConnectionChanged(bool connected) {} virtual int32_t runOnce(); // Check for dropped client connections @@ -48,6 +48,10 @@ class WiFiServerPort : public WiFiServer, private concurrency::OSThread void init(); + /// If an api server is running, we try to spit out debug 'serial' characters there + static void debugOut(char c); + + protected: int32_t runOnce(); }; diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 7e92919f..c60ae50e 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -1,10 +1,10 @@ #include "MQTT.h" #include "NodeDB.h" +#include "PowerFSM.h" #include "main.h" #include "mesh/Channels.h" #include "mesh/Router.h" #include "mesh/generated/mqtt.pb.h" -#include "PowerFSM.h" #include "sleep.h" #include #include @@ -60,42 +60,44 @@ MQTT::MQTT() : concurrency::OSThread("mqtt"), pubSub(mqttClient) pubSub.setCallback(mqttCallback); - // preflightSleepObserver.observe(&preflightSleep); + // preflightSleepObserver.observe(&preflightSleep); } void MQTT::reconnect() { - const char *serverAddr = "mqtt.meshtastic.org"; // default hostname - int serverPort = 1883; // default server port + if (wantsLink()) { + const char *serverAddr = "mqtt.meshtastic.org"; // default hostname + int serverPort = 1883; // default server port - if (*radioConfig.preferences.mqtt_server) - serverAddr = radioConfig.preferences.mqtt_server; // Override the default + if (*radioConfig.preferences.mqtt_server) + serverAddr = radioConfig.preferences.mqtt_server; // Override the default - String server = String(serverAddr); - int delimIndex = server.indexOf(':'); - if (delimIndex > 0) { - String port = server.substring(delimIndex+1, server.length()); - server[delimIndex] = 0; - serverPort = port.toInt(); - serverAddr = server.c_str(); + String server = String(serverAddr); + int delimIndex = server.indexOf(':'); + if (delimIndex > 0) { + String port = server.substring(delimIndex + 1, server.length()); + server[delimIndex] = 0; + serverPort = port.toInt(); + serverAddr = server.c_str(); + } + pubSub.setServer(serverAddr, serverPort); + + DEBUG_MSG("Connecting to MQTT server %s, port: %d\n", serverAddr, serverPort); + auto myStatus = (statusTopic + owner.id); + bool connected = pubSub.connect(owner.id, "meshdev", "large4cats", myStatus.c_str(), 1, true, "offline"); + if (connected) { + DEBUG_MSG("MQTT connected\n"); + enabled = true; // Start running background process again + runASAP = true; + + /// FIXME, include more information in the status text + bool ok = pubSub.publish(myStatus.c_str(), "online", true); + DEBUG_MSG("published %d\n", ok); + + sendSubscriptions(); + } else + DEBUG_MSG("Failed to contact MQTT server...\n"); } - pubSub.setServer(serverAddr, serverPort); - - DEBUG_MSG("Connecting to MQTT server %s, port: %d\n", serverAddr, serverPort); - auto myStatus = (statusTopic + owner.id); - bool connected = pubSub.connect(owner.id, "meshdev", "large4cats", myStatus.c_str(), 1, true, "offline"); - if (connected) { - DEBUG_MSG("MQTT connected\n"); - enabled = true; // Start running background process again - runASAP = true; - - /// FIXME, include more information in the status text - bool ok = pubSub.publish(myStatus.c_str(), "online", true); - DEBUG_MSG("published %d\n", ok); - - sendSubscriptions(); - } else - DEBUG_MSG("Failed to contact MQTT server...\n"); } void MQTT::sendSubscriptions() diff --git a/src/mqtt/MQTT.h b/src/mqtt/MQTT.h index f5ef9bf1..3f4c8f80 100644 --- a/src/mqtt/MQTT.h +++ b/src/mqtt/MQTT.h @@ -35,6 +35,10 @@ class MQTT : private concurrency::OSThread */ void onSend(const MeshPacket &mp, ChannelIndex chIndex); + /** Attempt to connect to server if necessary + */ + void reconnect(); + protected: virtual int32_t runOnce(); @@ -43,10 +47,6 @@ class MQTT : private concurrency::OSThread */ bool wantsLink() const; - /** Attempt to connect to server if necessary - */ - void reconnect(); - /** Tell the server what subscriptions we want (based on channels.downlink_enabled) */ void sendSubscriptions(); diff --git a/src/nimble/BluetoothUtil.cpp b/src/nimble/BluetoothUtil.cpp index 0618c73e..cd95c91e 100644 --- a/src/nimble/BluetoothUtil.cpp +++ b/src/nimble/BluetoothUtil.cpp @@ -21,6 +21,8 @@ static bool pinShowing; static uint32_t doublepressed; +static bool bluetoothActive; + static void startCb(uint32_t pin) { pinShowing = true; @@ -52,23 +54,27 @@ void updateBatteryLevel(uint8_t level) void deinitBLE() { - // DEBUG_MSG("Shutting down bluetooth\n"); - // ble_gatts_show_local(); + if (bluetoothActive) { + bluetoothActive = false; - // FIXME - do we need to dealloc things? - what needs to stay alive across light sleep? - auto ret = nimble_port_stop(); - assert(ret == ESP_OK); + // DEBUG_MSG("Shutting down bluetooth\n"); + // ble_gatts_show_local(); - nimble_port_deinit(); // teardown nimble datastructures + // FIXME - do we need to dealloc things? - what needs to stay alive across light sleep? + auto ret = nimble_port_stop(); + assert(ret == ESP_OK); - // DEBUG_MSG("BLE port_deinit done\n"); + nimble_port_deinit(); // teardown nimble datastructures - ret = esp_nimble_hci_and_controller_deinit(); - assert(ret == ESP_OK); + // DEBUG_MSG("BLE port_deinit done\n"); - // DEBUG_MSG("BLE task exiting\n"); + ret = esp_nimble_hci_and_controller_deinit(); + assert(ret == ESP_OK); - DEBUG_MSG("Done shutting down bluetooth\n"); + // DEBUG_MSG("BLE task exiting\n"); + + DEBUG_MSG("Done shutting down bluetooth\n"); + } } void loopBLE() @@ -479,6 +485,8 @@ void disablePin() doublepressed = millis(); } + + // This routine is called multiple times, once each time we come back from sleep void reinitBluetooth() { @@ -536,10 +544,10 @@ void reinitBluetooth() ble_store_config_init(); nimble_port_freertos_init(ble_host_task); + bluetoothActive = true; } bool bluetoothOn; -bool firstTime = 1; // Enable/disable bluetooth. void setBluetoothEnable(bool on) @@ -549,32 +557,15 @@ void setBluetoothEnable(bool on) bluetoothOn = on; if (on) { - Serial.printf("Pre BT: %u heap size\n", ESP.getFreeHeap()); - // ESP_ERROR_CHECK( heap_trace_start(HEAP_TRACE_LEAKS) ); - reinitBluetooth(); - - // Don't try to reconnect wifi before bluetooth is configured. - // WiFi is initialized from main.cpp in setup() . - if (firstTime) { - firstTime = 0; - } else { -#ifndef NO_ESP32 - initWifi(0); -#endif + if (!initWifi(0)) // if we are using wifi, don't turn on bluetooth also + { + Serial.printf("Pre BT: %u heap size\n", ESP.getFreeHeap()); + // ESP_ERROR_CHECK( heap_trace_start(HEAP_TRACE_LEAKS) ); + reinitBluetooth(); } } else { - - /* - // If WiFi is in use, disable shutting down the radio. - if (isWifiAvailable()) { - return; - } - */ - // shutdown wifi -#ifndef NO_ESP32 deinitWifi(); -#endif // We have to totally teardown our bluetooth objects to prevent leaks deinitBLE(); diff --git a/src/wifi-stubs.cpp b/src/wifi-stubs.cpp index 3d110c72..87470c52 100644 --- a/src/wifi-stubs.cpp +++ b/src/wifi-stubs.cpp @@ -5,7 +5,9 @@ //#include "mesh/wifi/WiFiAPClient.h" -void initWifi(bool forceSoftAP) {} +bool initWifi(bool forceSoftAP) { + return false; +} void deinitWifi() {} diff --git a/version.properties b/version.properties index fd3c5049..2dcc7972 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 1 minor = 2 -build = 44 +build = 45