diff --git a/docs/software/build-instructions.md b/docs/software/build-instructions.md
index 31008fda0..55ec8d7ad 100644
--- a/docs/software/build-instructions.md
+++ b/docs/software/build-instructions.md
@@ -39,9 +39,20 @@ cd Meshtastic-device
## Decoding stack traces
+### Option 1
+
If you get a crash, you can decode the addresses from the `Backtrace:` line:
1. Save the `Backtrace: 0x....` line to a file, e.g., `backtrace.txt`.
2. Run `bin/exception_decoder.py backtrace.txt` (this uses symbols from the
last `firmware.elf`, so you must be running the same binary that's still in
your `.pio/build` directory).
+
+### Option 2
+
+You can run the exception decoder to monitor the serial output and decode backtraces in real time.
+
+1. From within PlatformIO, open a new terminal.
+2. At the the terminal, enter:
+ `pio device monitor --port /dev/cu.SLAB_USBtoUART -f esp32_exception_decoder`
+ Replace the value of port with the location of your serial port.
diff --git a/platformio.ini b/platformio.ini
index d5fbc07f2..34667d2ca 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -9,7 +9,7 @@
; https://docs.platformio.org/page/projectconf.html
[platformio]
-default_envs = tbeam # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
+default_envs = linux # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
;default_envs = heltec # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
[common]
@@ -65,7 +65,7 @@ lib_deps =
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
https://github.com/meshtastic/arduino-fsm.git#2f106146071fc7bc620e1e8d4b88dc4e0266ce39
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
- https://github.com/meshtastic/RadioLib.git#8657380241bce681c33aab46598bbf13b11f876c
+ https://github.com/meshtastic/RadioLib.git#07de964e929238949035fb0d5887026a3058df1a
https://github.com/meshtastic/TinyGPSPlus.git#9c1d584d2469523381e077b0b9c1bf868d6c0206
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
Wire ; explicitly needed here because the AXP202 library forgets to add it
@@ -183,7 +183,7 @@ build_flags =
-Isdk-nrfxlib/crypto/nrf_oberon/include -Lsdk-nrfxlib/crypto/nrf_oberon/lib/cortex-m4/hard-float/ -lliboberon_3.0.3
;-DCFG_DEBUG=3
src_filter =
- ${arduino_base.src_filter} - - -
+ ${arduino_base.src_filter} - - - -
lib_ignore =
BluetoothOTA
monitor_port = /dev/ttyACM1
@@ -314,6 +314,9 @@ src_filter = ${env.src_filter} - - - -
build_flags = ${arduino_base.build_flags} -O0
framework = arduino
board = linux_x86_64
+lib_deps =
+ ${arduino_base.lib_deps}
+ rweather/Crypto
; The GenieBlocks LORA prototype board
[env:genieblocks_lora]
diff --git a/proto b/proto
index dfe7bc121..75078afe4 160000
--- a/proto
+++ b/proto
@@ -1 +1 @@
-Subproject commit dfe7bc1217a00c23eecb9dfcf1d56fe95ebddc3b
+Subproject commit 75078afe43934f4ce15ef86ebc6950658a170145
diff --git a/src/configuration.h b/src/configuration.h
index 4f59c840a..79d1009ca 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -394,7 +394,7 @@ along with this program. If not, see .
#define USE_RF95
#define LORA_DIO0 26 // a No connect on the SX1262 module
-#define LORA_RESET 23
+#define LORA_RESET RADIOLIB_NC
#define LORA_DIO1 33 // Not really used
#define LORA_DIO2 32 // Not really used
@@ -402,7 +402,7 @@ along with this program. If not, see .
#define RF95_SCK 5
#define RF95_MISO 19
#define RF95_MOSI 27
-#define RF95_NSS 18
+#define RF95_NSS RADIOLIB_NC // the ch341f spi controller does CS for us
#endif
diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp
index c0e336f0c..04aa2c7af 100644
--- a/src/gps/GPS.cpp
+++ b/src/gps/GPS.cpp
@@ -239,6 +239,7 @@ int32_t GPS::runOnce()
}
// We've been awake too long - force sleep
+ now = millis();
auto wakeTime = getWakeTime();
bool tooLong = wakeTime != UINT32_MAX && (now - lastWakeStartMsec) > wakeTime;
diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp
index a0cad4273..545ef2b90 100644
--- a/src/mesh/PhoneAPI.cpp
+++ b/src/mesh/PhoneAPI.cpp
@@ -21,11 +21,17 @@ void PhoneAPI::init()
observe(&service.fromNumChanged);
}
+PhoneAPI::~PhoneAPI() {
+ close();
+}
+
void PhoneAPI::close() {
unobserve();
state = STATE_SEND_NOTHING;
+ bool oldConnected = isConnected;
isConnected = false;
- onConnectionChanged(isConnected);
+ if(oldConnected != isConnected)
+ onConnectionChanged(isConnected);
}
void PhoneAPI::checkConnectionTimeout()
diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h
index 202f7fa2d..3cfd97441 100644
--- a/src/mesh/PhoneAPI.h
+++ b/src/mesh/PhoneAPI.h
@@ -55,12 +55,15 @@ class PhoneAPI
public:
PhoneAPI();
+ /// Destructor - calls close()
+ virtual ~PhoneAPI();
+
/// Do late init that can't happen at constructor time
virtual void init();
// Call this when the client drops the connection, resets the state to STATE_SEND_NOTHING
- // Unregisters our observer
- void close();
+ // Unregisters our observer. A closed connection **can** be reopened by calling init again.
+ virtual void close();
/**
* Handle a ToRadio protobuf
diff --git a/src/mesh/RF95Interface.cpp b/src/mesh/RF95Interface.cpp
index 60596468b..a94a8d129 100644
--- a/src/mesh/RF95Interface.cpp
+++ b/src/mesh/RF95Interface.cpp
@@ -12,7 +12,7 @@
#define POWER_DEFAULT 17 // How much power to use if the user hasn't set a power level
RF95Interface::RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi)
- : RadioLibInterface(cs, irq, rst, 0, spi)
+ : RadioLibInterface(cs, irq, rst, RADIOLIB_NC, spi)
{
// FIXME - we assume devices never get destroyed
}
diff --git a/src/mesh/RF95Interface.h b/src/mesh/RF95Interface.h
index 91f5728c5..ebebe3c79 100644
--- a/src/mesh/RF95Interface.h
+++ b/src/mesh/RF95Interface.h
@@ -14,6 +14,9 @@ class RF95Interface : public RadioLibInterface
public:
RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi);
+ /// Some boards (Pinetab Lora module) have broken IRQ wires, so we need to poll via i2c registers
+ bool isIRQPending() { return lora->getPendingIRQ(); }
+
/// Initialise the Driver transport hardware and software.
/// Make sure the Driver is properly configured before calling init().
/// \return true if initialisation succeeded.
diff --git a/src/esp32/WiFiServerAPI.cpp b/src/mesh/wifi/WiFiServerAPI.cpp
similarity index 67%
rename from src/esp32/WiFiServerAPI.cpp
rename to src/mesh/wifi/WiFiServerAPI.cpp
index 3b11c2ae4..1f087cc10 100644
--- a/src/esp32/WiFiServerAPI.cpp
+++ b/src/mesh/wifi/WiFiServerAPI.cpp
@@ -5,7 +5,7 @@
WiFiServerAPI::WiFiServerAPI(WiFiClient &_client) : StreamAPI(&client), client(_client)
{
- DEBUG_MSG("Incoming connection from %s\n", client.remoteIP().toString().c_str());
+ DEBUG_MSG("Incoming wifi connection\n");
}
WiFiServerAPI::~WiFiServerAPI()
@@ -28,18 +28,19 @@ void WiFiServerAPI::onConnectionChanged(bool connected)
}
}
-void WiFiServerAPI::loop()
+/// override close to also shutdown the TCP link
+void WiFiServerAPI::close() {
+ client.stop(); // drop tcp connection
+ StreamAPI::close();
+}
+
+bool WiFiServerAPI::loop()
{
if (client.connected()) {
StreamAPI::loop();
- } else if(isConnected) {
- // If our API link was up, shut it down
-
- DEBUG_MSG("Client dropped connection, closing API client\n");
- // Note: we can't call delete here because this object includes other state
- // besides the stream API. Instead kill it later when we start a new instance
- // delete this;
- close();
+ return true;
+ } else {
+ return false;
}
}
@@ -58,15 +59,25 @@ int32_t WiFiServerPort::runOnce()
auto client = available();
if (client) {
// Close any previous connection (see FIXME in header file)
- if (openAPI)
+ if (openAPI) {
+ DEBUG_MSG("Force closing previous TCP connection\n");
delete openAPI;
+ }
openAPI = new WiFiServerAPI(client);
}
if (openAPI) {
// Allow idle processing so the API can read from its incoming stream
- openAPI->loop();
+ if(!openAPI->loop()) {
+ // If our API link was up, shut it down
+
+ DEBUG_MSG("Client dropped connection, closing API client\n");
+ // Note: we can't call delete here because this object includes other state
+ // besides the stream API. Instead kill it later when we start a new instance
+ delete openAPI;
+ openAPI = NULL;
+ }
return 0; // run fast while our API server is running
} else
return 100; // only check occasionally for incoming connections
diff --git a/src/esp32/WiFiServerAPI.h b/src/mesh/wifi/WiFiServerAPI.h
similarity index 83%
rename from src/esp32/WiFiServerAPI.h
rename to src/mesh/wifi/WiFiServerAPI.h
index 19f99cbc5..963800203 100644
--- a/src/esp32/WiFiServerAPI.h
+++ b/src/mesh/wifi/WiFiServerAPI.h
@@ -18,7 +18,11 @@ class WiFiServerAPI : public StreamAPI
virtual ~WiFiServerAPI();
- virtual void loop(); // Check for dropped client connections
+ /// @return true if we want to keep running, or false if we are ready to be destroyed
+ virtual bool loop(); // Check for dropped client connections
+
+ /// override close to also shutdown the TCP link
+ virtual void close();
protected:
/// Hookable to find out when connection changes
diff --git a/src/meshwifi/meshhttp.cpp b/src/meshwifi/meshhttp.cpp
index 8814dc9d5..76e9616f7 100644
--- a/src/meshwifi/meshhttp.cpp
+++ b/src/meshwifi/meshhttp.cpp
@@ -495,6 +495,9 @@ void handleStaticBrowse(HTTPRequest *req, HTTPResponse *res)
std::string paramValDelete;
std::string paramValEdit;
+ DEBUG_MSG("Static Browse - Disabling keep-alive\n");
+ res->setHeader("Connection", "close");
+
// Set a default content type
res->setHeader("Content-Type", "text/html");
@@ -560,9 +563,7 @@ void handleStaticBrowse(HTTPRequest *req, HTTPResponse *res)
}
res->println("
Upload new file
");
- res->println("*** This interface is experimental ***
");
- res->println("This form allows you to upload files. Keep your filenames very short and files small. Big filenames and big "
- "files (>200k) are a known problem.
");
+ res->println("This form allows you to upload files. Keep your filenames small and files under 200k.
");
res->println("