diff --git a/bin/build-all.sh b/bin/build-all.sh index 5021680c..c27760c4 100755 --- a/bin/build-all.sh +++ b/bin/build-all.sh @@ -14,6 +14,8 @@ BOARDS_ESP32="tlora-v2 tlora-v1 tlora-v2-1-1.6 tbeam heltec tbeam0.7" # FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine BOARDS_NRF52="lora-relay-v1" +NUM_JOBS=2 + OUTDIR=release/latest # We keep all old builds (and their map files in the archive dir) @@ -49,7 +51,7 @@ function do_build() { basename=universal/firmware-$BOARD-$VERSION fi - pio run --jobs 4 --environment $BOARD # -v + pio run --jobs $NUM_JOBS --environment $BOARD # -v SRCELF=.pio/build/$BOARD/firmware.elf cp $SRCELF $OUTDIR/elfs/$basename.elf diff --git a/bin/platformio-custom.py b/bin/platformio-custom.py index d56cc09f..ec9dd454 100644 --- a/bin/platformio-custom.py +++ b/bin/platformio-custom.py @@ -8,7 +8,7 @@ config.read(prefsLoc) version = dict(config.items('VERSION')) verStr = "{}.{}.{}".format(version["major"], version["minor"], version["build"]) -print(f"Using meshtastic platform-custom.py, firmare version {verStr}") +print("Using meshtastic platform-custom.py, firmare version " + verStr) # General options that are passed to the C and C++ compilers projenv.Append(CCFLAGS=[ diff --git a/docs/software/TODO.md b/docs/software/TODO.md index c08ddabe..f96d2acb 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -4,6 +4,8 @@ You probably don't care about this section - skip to the next one. For app cleanup: +* DONE writeup nice python options docs (common cases, link to protobuf docs) +* have android app link to user manual * DONE only do wantReplies once per packet type, if we change network settings force it again * update positions and nodeinfos based on packets we just merely witness on the mesh. via isPromsciousPort bool, remove sniffing * DONE make device build always have a valid version @@ -36,7 +38,6 @@ For app cleanup: * fix the RTC drift bug * move python ping functionality into device, reply with rxsnr info * use channels for gpio security https://github.com/meshtastic/Meshtastic-device/issues/104 -* generate autodocs * MeshPackets for sending should be reference counted so that API clients would have the option of checking sent status (would allow removing the nasty 30 sec timer in gpio watch sending) For high speed/lots of devices/short range tasks: diff --git a/docs/software/esp32-arduino-build-notes.md b/docs/software/esp32-arduino-build-notes.md index 94b64f62..1b5a5da0 100644 --- a/docs/software/esp32-arduino-build-notes.md +++ b/docs/software/esp32-arduino-build-notes.md @@ -10,7 +10,7 @@ you'll automatically get our fixed libraries. IDF release/v3.3 46b12a560 IDF release/v3.3 367c3c09c https://docs.espressif.com/projects/esp-idf/en/release-v3.3/get-started/linux-setup.html - kevinh@kevin-server:~/development/meshtastic/esp32-arduino-lib-builder\$ python /home/kevinh/development/meshtastic/esp32-arduino-lib-builder/esp-idf/components/esptool*py/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dout --flash_freq 40m --flash_size detect 0x1000 /home/kevinh/development/meshtastic/esp32-arduino-lib-builder/build/bootloader/bootloader.bin + kevinh@kevin-server:~/development/meshtastic/esp32-arduino-lib-builder\$ python /home/kevinh/development/meshtastic/ cp -a out/tools/sdk/* components/arduino/tools/sdk cp -ar components/arduino/* ~/.platformio/packages/framework-arduinoespressif32 @@ -21,3 +21,9 @@ you'll automatically get our fixed libraries. cp -ar out/tools/sdk/* ~/.platformio/packages/framework-arduinoespressif32/tools/sdk ``` + +How to flash new bootloader + +``` +esp32-arduino-lib-builder/esp-idf/components/esptool*py/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dout --flash_freq 40m --flash_size detect 0x1000 /home/kevinh/development/meshtastic/esp32-arduino-lib-builder/build/bootloader/bootloader.bin +``` diff --git a/platformio.ini b/platformio.ini index 015aa105..50d381c8 100644 --- a/platformio.ini +++ b/platformio.ini @@ -103,7 +103,7 @@ lib_deps = # board_build.ldscript = linker/esp32.extram.bss.ld lib_ignore = segger_rtt platform_packages = - framework-arduinoespressif32@https://github.com/meshtastic/arduino-esp32.git#2814f110aa618429bdd9a0a2d6a93c55f29f87a6 + framework-arduinoespressif32@https://github.com/meshtastic/arduino-esp32.git#352c8ea7cb73f10433ed139f34251979c470ad56 ; customize the partition table ; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables diff --git a/proto b/proto index 75078afe..020ef9ee 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 75078afe43934f4ce15ef86ebc6950658a170145 +Subproject commit 020ef9eea8129756a0b45be5a3900b0355be4451 diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index 7894361d..85e08f53 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -144,12 +144,12 @@ static void onEnter() uint32_t now = millis(); - if (now - lastPingMs > 30 * 1000) { // if more than a minute since our last press, ask node we are looking at to update their state + if (now - lastPingMs > + 30 * 1000) { // if more than a minute since our last press, ask node we are looking at to update their state if (displayedNodeNum) service.sendNetworkPing(displayedNodeNum, true); // Refresh the currently displayed node lastPingMs = now; } - } static void screenPress() @@ -171,11 +171,18 @@ Fsm powerFSM(&stateBOOT); void PowerFSM_setup() { + bool isRouter = radioConfig.preferences.is_router; + // If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON // We assume routers might be powered all the time, but from a low current (solar) source - bool isLowPower = radioConfig.preferences.is_low_power; - bool hasPower = !isLowPower && powerStatus && powerStatus->getHasUSB(); - bool isRouter = radioConfig.preferences.is_router; + bool isLowPower = radioConfig.preferences.is_low_power || isRouter; + + /* To determine if we're externally powered, assumptions + 1) If we're powered up and there's no battery, we must be getting power externally. + 2) If we detect USB power from the power management chip, we must be getting power externally. + */ + bool hasPower = (powerStatus && !powerStatus->getHasBattery()) || (!isLowPower && powerStatus && powerStatus->getHasUSB()); + DEBUG_MSG("PowerFSM init, USB power=%d\n", hasPower); powerFSM.add_timed_transition(&stateBOOT, hasPower ? &statePOWER : &stateON, 3 * 1000, NULL, "boot timeout"); diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 0205aa66..541b55c7 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -1,6 +1,9 @@ #include "RedirectablePrint.h" #include "configuration.h" #include +#include +#include +#include "concurrency/OSThread.h" /** * A printer that doesn't go anywhere @@ -15,10 +18,82 @@ void RedirectablePrint::setDestination(Print *_dest) size_t RedirectablePrint::write(uint8_t c) { + // Always send the characters to our segger JTAG debugger #ifdef SEGGER_STDOUT_CH SEGGER_RTT_PutCharSkip(SEGGER_STDOUT_CH, c); #endif dest->write(c); return 1; // We always claim one was written, rather than trusting what the serial port said (which could be zero) +} + +size_t RedirectablePrint::vprintf(const char *format, va_list arg) +{ + va_list copy; + + va_copy(copy, arg); + int len = vsnprintf(printBuf, printBufLen, format, copy); + va_end(copy); + if (len < 0) { + va_end(arg); + return 0; + }; + if (len >= printBufLen) { + delete[] printBuf; + printBufLen *= 2; + printBuf = new char[printBufLen]; + len = vsnprintf(printBuf, printBufLen, format, arg); + } + + len = Print::write(printBuf, len); + return len; +} + +#define SEC_PER_DAY 86400 +#define SEC_PER_HOUR 3600 +#define SEC_PER_MIN 60 + +size_t RedirectablePrint::logDebug(const char *format, ...) +{ + va_list arg; + va_start(arg, format); + + // Cope with 0 len format strings, but look for new line terminator + bool hasNewline = *format && format[strlen(format) - 1] == '\n'; + + size_t r = 0; + + // If we are the first message on a report, include the header + if (!isContinuationMessage) { + struct timeval tv; + if (!gettimeofday(&tv, NULL)) { + long hms = tv.tv_sec % SEC_PER_DAY; + //hms += tz.tz_dsttime * SEC_PER_HOUR; + //hms -= tz.tz_minuteswest * SEC_PER_MIN; + // mod `hms` to ensure in positive range of [0...SEC_PER_DAY) + hms = (hms + SEC_PER_DAY) % SEC_PER_DAY; + + // Tear apart hms into h:m:s + int hour = hms / SEC_PER_HOUR; + int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN; + int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN + + r += printf("%02d:%02d:%02d ", hour, min, sec); + } else + r += printf("??:??:?? "); + + auto thread = concurrency::OSThread::currentThread; + if(thread) { + print("["); + print(thread->ThreadName); + print("] "); + } + } + + r += vprintf(format, arg); + va_end(arg); + + isContinuationMessage = !hasNewline; + + return r; } \ No newline at end of file diff --git a/src/RedirectablePrint.h b/src/RedirectablePrint.h index 2d525118..ca208612 100644 --- a/src/RedirectablePrint.h +++ b/src/RedirectablePrint.h @@ -1,6 +1,7 @@ #pragma once #include +#include /** * A Printable that can be switched to squirt its bytes to a different sink. @@ -11,6 +12,13 @@ class RedirectablePrint : public Print { Print *dest; + /// We dynamically grow this scratch buffer if necessary + char *printBuf = new char[64]; + size_t printBufLen = 64; + + /// Used to allow multiple logDebug messages to appear on a single log line + bool isContinuationMessage = false; + public: RedirectablePrint(Print *_dest) : dest(_dest) {} @@ -20,6 +28,21 @@ class RedirectablePrint : public Print void setDestination(Print *dest); virtual size_t write(uint8_t c); + + /** + * Debug logging print message + * + * If the provide format string ends with a newline we assume it is the final print of a single + * log message. Otherwise we assume more prints will come before the log message ends. This + * allows you to call logDebug a few times to build up a single log message line if you wish. + * + * FIXME, eventually add log levels (INFO, WARN, ERROR) and subsystems. Move into + * a different class. + */ + size_t logDebug(const char * format, ...) __attribute__ ((format (printf, 2, 3))); + + /** like printf but va_list based */ + size_t vprintf(const char *format, va_list arg); }; class NoopPrint : public Print diff --git a/src/concurrency/OSThread.cpp b/src/concurrency/OSThread.cpp index 916e68e1..58a0d59c 100644 --- a/src/concurrency/OSThread.cpp +++ b/src/concurrency/OSThread.cpp @@ -14,6 +14,8 @@ bool OSThread::showRun = false; /// Show debugging info for threads we decide not to run; bool OSThread::showWaiting = false; +const OSThread *OSThread::currentThread; + ThreadController mainController, timerController; InterruptableDelay mainDelay; @@ -68,12 +70,15 @@ bool OSThread::shouldRun(unsigned long time) void OSThread::run() { + currentThread = this; auto newDelay = runOnce(); runned(); if (newDelay >= 0) setInterval(newDelay); + + currentThread = NULL; } } // namespace concurrency diff --git a/src/concurrency/OSThread.h b/src/concurrency/OSThread.h index dc600387..3be149d5 100644 --- a/src/concurrency/OSThread.h +++ b/src/concurrency/OSThread.h @@ -42,6 +42,10 @@ class OSThread : public Thread static bool showWaiting; public: + + /// For debug printing only (might be null) + static const OSThread *currentThread; + OSThread(const char *name, uint32_t period = 0, ThreadController *controller = &mainController); virtual ~OSThread(); diff --git a/src/configuration.h b/src/configuration.h index 28eea052..6fa07ce6 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -428,7 +428,7 @@ along with this program. If not, see . #define DEBUG_MSG(...) SEGGER_RTT_printf(0, __VA_ARGS__) #else #ifdef DEBUG_PORT -#define DEBUG_MSG(...) DEBUG_PORT.printf(__VA_ARGS__) +#define DEBUG_MSG(...) DEBUG_PORT.logDebug(__VA_ARGS__) #else #define DEBUG_MSG(...) #endif diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 314b4c31..c0e336f0 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -158,7 +158,7 @@ uint32_t GPS::getWakeTime() const return t; // already maxint if (t == 0) - t = 15 * 60; // Allow up to 5 mins for each attempt (probably will be much less if we can find sats) + t = radioConfig.preferences.is_router ? 5 * 60 : 15 * 60; // Allow up to 15 mins for each attempt (probably will be much less if we can find sats) or less if a router t *= 1000; // msecs @@ -179,8 +179,8 @@ uint32_t GPS::getSleepTime() const if (t == UINT32_MAX) return t; // already maxint - if (t == 0) - t = 2 * 60; // 2 mins + if (t == 0) // default - unset in preferences + t = radioConfig.preferences.is_router ? 24 * 60 * 60 : 2 * 60; // 2 mins or once per day for routers t *= 1000; diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 3f98969d..ecaa216f 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -912,7 +912,9 @@ void Screen::blink() { void Screen::handlePrint(const char *text) { - DEBUG_MSG("Screen: %s", text); + // the string passed into us probably has a newline, but that would confuse the logging system + // so strip it + DEBUG_MSG("Screen: %.*s\n", strlen(text) - 1, text); if (!useDisplay || !showingNormalScreen) return; diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index e8c230ce..5174f564 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -147,23 +147,53 @@ their nodes */ const char *getChannelName(); +/* + If is_router is set, we use a number of different default values + + # FIXME - after tuning, move these params into the on-device defaults based on is_router and is_low_power + + # prefs.position_broadcast_secs = FIXME possibly broadcast only once an hr + prefs.wait_bluetooth_secs = 1 # Don't stay in bluetooth mode + prefs.mesh_sds_timeout_secs = never + prefs.phone_sds_timeout_sec = never + # try to stay in light sleep one full day, then briefly wake and sleep again + + prefs.ls_secs = oneday + + prefs.send_owner_interval = 2 # Send an owner packet every other network ping + prefs.position_broadcast_secs = 12 hours # send either position or owner every 12hrs + + # get a new GPS position once per day + prefs.gps_update_interval = oneday + + prefs.is_low_power = True + + # allow up to five minutes for each new GPS lock attempt + prefs.gps_attempt_time = 300 +*/ + +// Our delay functions check for this for times that should never expire +#define DELAY_FOREVER 0xffffffff + +#define IF_ROUTER(routerVal, normalVal) (radioConfig.preferences.is_router ? (routerVal) : (normalVal)) + #define PREF_GET(name, defaultVal) \ inline uint32_t getPref_##name() { return radioConfig.preferences.name ? radioConfig.preferences.name : (defaultVal); } -PREF_GET(send_owner_interval, 4) -PREF_GET(position_broadcast_secs, 15 * 60) +PREF_GET(send_owner_interval, IF_ROUTER(2, 4)) +PREF_GET(position_broadcast_secs, IF_ROUTER(12 * 60 * 60, 15 * 60)) // Each time we wake into the DARK state allow 1 minute to send and receive BLE packets to the phone -PREF_GET(wait_bluetooth_secs, 60) +PREF_GET(wait_bluetooth_secs, IF_ROUTER(1, 60)) PREF_GET(screen_on_secs, 60) -PREF_GET(mesh_sds_timeout_secs, 2 * 60 * 60) -PREF_GET(phone_sds_timeout_sec, 2 * 60 * 60) +PREF_GET(mesh_sds_timeout_secs, IF_ROUTER(DELAY_FOREVER, 2 * 60 * 60)) +PREF_GET(phone_sds_timeout_sec, IF_ROUTER(DELAY_FOREVER, 2 * 60 * 60)) PREF_GET(sds_secs, 365 * 24 * 60 * 60) // We default to sleeping (with bluetooth off for 5 minutes at a time). This seems to be a good tradeoff between // latency for the user sending messages and power savings because of not having to run (expensive) ESP32 bluetooth -PREF_GET(ls_secs, 5 * 60) +PREF_GET(ls_secs, IF_ROUTER(24 * 60 * 60, 5 * 60)) PREF_GET(phone_timeout_secs, 15 * 60) PREF_GET(min_wake_secs, 10) diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index e122c45c..754f0d38 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -100,7 +100,7 @@ void PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength) size_t PhoneAPI::getFromRadio(uint8_t *buf) { if (!available()) { - DEBUG_MSG("getFromRadio, !available\n"); + // DEBUG_MSG("getFromRadio, !available\n"); return 0; } @@ -226,7 +226,7 @@ bool PhoneAPI::available() if (!packetForPhone) packetForPhone = service.getForPhone(); bool hasPacket = !!packetForPhone; - DEBUG_MSG("available hasPacket=%d\n", hasPacket); + // DEBUG_MSG("available hasPacket=%d\n", hasPacket); return hasPacket; } diff --git a/src/mesh/mesh.pb.h b/src/mesh/mesh.pb.h index bda4873b..92bab3ae 100644 --- a/src/mesh/mesh.pb.h +++ b/src/mesh/mesh.pb.h @@ -106,7 +106,6 @@ typedef struct _Position { typedef struct _RadioConfig_UserPreferences { uint32_t position_broadcast_secs; uint32_t send_owner_interval; - uint32_t num_missed_to_fail; uint32_t wait_bluetooth_secs; uint32_t screen_on_secs; uint32_t phone_timeout_secs; @@ -284,7 +283,7 @@ extern "C" { #define MeshPacket_init_default {0, 0, 0, {SubPacket_init_default}, 0, 0, 0, 0, 0, 0} #define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0} #define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default, false, ChannelSettings_init_default} -#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}} +#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}} #define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0} #define MyNodeInfo_init_default {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0} #define DeviceState_init_default {false, RadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0, 0, {ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default}} @@ -299,7 +298,7 @@ extern "C" { #define MeshPacket_init_zero {0, 0, 0, {SubPacket_init_zero}, 0, 0, 0, 0, 0, 0} #define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0} #define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero, false, ChannelSettings_init_zero} -#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}} +#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}} #define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0} #define MyNodeInfo_init_zero {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0} #define DeviceState_init_zero {false, RadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0, 0, {ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero}} @@ -340,7 +339,6 @@ extern "C" { #define Position_time_tag 9 #define RadioConfig_UserPreferences_position_broadcast_secs_tag 1 #define RadioConfig_UserPreferences_send_owner_interval_tag 2 -#define RadioConfig_UserPreferences_num_missed_to_fail_tag 3 #define RadioConfig_UserPreferences_wait_bluetooth_secs_tag 4 #define RadioConfig_UserPreferences_screen_on_secs_tag 5 #define RadioConfig_UserPreferences_phone_timeout_secs_tag 6 @@ -509,7 +507,6 @@ X(a, STATIC, OPTIONAL, MESSAGE, channel_settings, 2) #define RadioConfig_UserPreferences_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, UINT32, position_broadcast_secs, 1) \ X(a, STATIC, SINGULAR, UINT32, send_owner_interval, 2) \ -X(a, STATIC, SINGULAR, UINT32, num_missed_to_fail, 3) \ X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 4) \ X(a, STATIC, SINGULAR, UINT32, screen_on_secs, 5) \ X(a, STATIC, SINGULAR, UINT32, phone_timeout_secs, 6) \ @@ -661,11 +658,11 @@ extern const pb_msgdesc_t ToRadio_msg; #define SubPacket_size 275 #define MeshPacket_size 320 #define ChannelSettings_size 84 -#define RadioConfig_size 314 -#define RadioConfig_UserPreferences_size 225 +#define RadioConfig_size 308 +#define RadioConfig_UserPreferences_size 219 #define NodeInfo_size 132 #define MyNodeInfo_size 110 -#define DeviceState_size 5824 +#define DeviceState_size 5818 #define DebugString_size 258 #define FromRadio_size 329 #define ToRadio_size 323 diff --git a/src/meshwifi/meshhttp.cpp b/src/meshwifi/meshhttp.cpp index ebff1e7b..b6953c32 100644 --- a/src/meshwifi/meshhttp.cpp +++ b/src/meshwifi/meshhttp.cpp @@ -4,6 +4,7 @@ #include "main.h" #include "meshhttpStatic.h" #include "meshwifi/meshwifi.h" +#include "PowerFSM.h" #include "sleep.h" #include #include @@ -61,6 +62,7 @@ void handle404(HTTPRequest *req, HTTPResponse *res); void handleFormUpload(HTTPRequest *req, HTTPResponse *res); void handleScanNetworks(HTTPRequest *req, HTTPResponse *res); void handleSpiffsBrowseStatic(HTTPRequest *req, HTTPResponse *res); +void handleSpiffsDeleteStatic(HTTPRequest *req, HTTPResponse *res); void handleBlinkLED(HTTPRequest *req, HTTPResponse *res); void middlewareSpeedUp240(HTTPRequest *req, HTTPResponse *res, std::function next); @@ -78,7 +80,8 @@ char contentTypes[][2][32] = {{".txt", "text/plain"}, {".html", "text/html"} {".js", "text/javascript"}, {".png", "image/png"}, {".jpg", "image/jpg"}, {".gz", "application/gzip"}, {".gif", "image/gif"}, {".json", "application/json"}, - {".css", "text/css"}, {"", ""}}; + {".css", "text/css"}, {".ico","image/vnd.microsoft.icon"}, + {".svg", "image/svg+xml"}, {"", ""}}; void handleWebResponse() { @@ -246,6 +249,7 @@ void initWebServer() ResourceNode *nodeJsonScanNetworks = new ResourceNode("/json/scanNetworks", "GET", &handleScanNetworks); ResourceNode *nodeJsonBlinkLED = new ResourceNode("/json/blink", "POST", &handleBlinkLED); ResourceNode *nodeJsonSpiffsBrowseStatic = new ResourceNode("/json/spiffs/browse/static/", "GET", &handleSpiffsBrowseStatic); + ResourceNode *nodeJsonDelete = new ResourceNode("/json/spiffs/delete/static", "DELETE", &handleSpiffsDeleteStatic); // Secure nodes secureServer->registerNode(nodeAPIv1ToRadioOptions); @@ -262,6 +266,7 @@ void initWebServer() secureServer->registerNode(nodeJsonScanNetworks); secureServer->registerNode(nodeJsonBlinkLED); secureServer->registerNode(nodeJsonSpiffsBrowseStatic); + secureServer->registerNode(nodeJsonDelete); secureServer->setDefaultNode(node404); secureServer->addMiddleware(&middlewareSpeedUp240); @@ -281,6 +286,7 @@ void initWebServer() insecureServer->registerNode(nodeJsonScanNetworks); insecureServer->registerNode(nodeJsonBlinkLED); insecureServer->registerNode(nodeJsonSpiffsBrowseStatic); + insecureServer->registerNode(nodeJsonDelete); insecureServer->setDefaultNode(node404); insecureServer->addMiddleware(&middlewareSpeedUp160); @@ -301,6 +307,10 @@ void middlewareSpeedUp240(HTTPRequest *req, HTTPResponse *res, std::functiongetParams(); + std::string paramValDelete; + + res->setHeader("Content-Type", "application/json"); + if (params->getQueryParameter("delete", paramValDelete)) { + std::string pathDelete = "/" + paramValDelete; + if (SPIFFS.remove(pathDelete.c_str())) { + Serial.println(pathDelete.c_str()); + res->println("{"); + res->println("\"status\": \"ok\""); + res->println("}"); + return; + } else { + Serial.println(pathDelete.c_str()); + res->println("{"); + res->println("\"status\": \"Error\""); + res->println("}"); + return; + } + } +} + void handleStaticBrowse(HTTPRequest *req, HTTPResponse *res) { // Get access to the parameters @@ -911,8 +949,6 @@ void handleRoot(HTTPRequest *req, HTTPResponse *res) { res->setHeader("Content-Type", "text/html"); - randomSeed(millis()); - res->setHeader("Set-Cookie", "mt_session=" + httpsserver::intToString(random(1, 9999999)) + "; Expires=Wed, 20 Apr 2049 4:20:00 PST"); diff --git a/src/meshwifi/meshwifi.cpp b/src/meshwifi/meshwifi.cpp index 16ae6185..54358077 100644 --- a/src/meshwifi/meshwifi.cpp +++ b/src/meshwifi/meshwifi.cpp @@ -40,12 +40,14 @@ bool isWifiAvailable() const char *wifiName = radioConfig.preferences.wifi_ssid; const char *wifiPsw = radioConfig.preferences.wifi_password; - // strcpy(radioConfig.preferences.wifi_ssid, ""); - // strcpy(radioConfig.preferences.wifi_password, ""); + // 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 && *wifiPsw) { return 1; @@ -221,9 +223,16 @@ static void WiFiEvent(WiFiEvent_t event) DEBUG_MSG("Obtained IP address: \n"); Serial.println(WiFi.localIP()); - // Start web server - initWebServer(); - initApiServer(); + 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"); + } break; case SYSTEM_EVENT_STA_LOST_IP: @@ -253,7 +262,7 @@ static void WiFiEvent(WiFiEvent_t event) APStartupComplete = true; } else { - DEBUG_MSG("... Not starting network services\n"); + DEBUG_MSG("... Not starting network services (They're already running)\n"); } break; diff --git a/src/plugins/RemoteHardwarePlugin.cpp b/src/plugins/RemoteHardwarePlugin.cpp index e9f25e51..e63e05cf 100644 --- a/src/plugins/RemoteHardwarePlugin.cpp +++ b/src/plugins/RemoteHardwarePlugin.cpp @@ -89,7 +89,7 @@ bool RemoteHardwarePlugin::handleReceivedProtobuf(const MeshPacket &req, const H lastWatchMsec = 0; // Force a new publish soon previousWatch = ~watchGpios; // generate a 'previous' value which is guaranteed to not match (to force an initial publish) enabled = true; // Let our thread run at least once - DEBUG_MSG("Now watching GPIOs 0x%x\n", watchGpios); + DEBUG_MSG("Now watching GPIOs 0x%llx\n", watchGpios); break; } @@ -114,7 +114,7 @@ int32_t RemoteHardwarePlugin::runOnce() { if(curVal != previousWatch) { previousWatch = curVal; - DEBUG_MSG("Broadcasting GPIOS 0x%x changed!\n", curVal); + DEBUG_MSG("Broadcasting GPIOS 0x%llx changed!\n", curVal); // Something changed! Tell the world with a broadcast message HardwareMessage reply = HardwareMessage_init_default;