From c06b7b2b484ff3dd9178bf9a95b16922dc279427 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 27 Dec 2020 16:06:30 +0800 Subject: [PATCH 1/2] add misc mqtt ideas --- docs/software/mqtt.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/software/mqtt.md b/docs/software/mqtt.md index 06ec7bb0f..2054c56d3 100644 --- a/docs/software/mqtt.md +++ b/docs/software/mqtt.md @@ -103,12 +103,16 @@ If the channelid 'well known'/public it can be decrypted by a web service, in wh clear/MESHID/NODEID/PORTID -FIXME, the payload published on the topic, will include the message, and full information about arrival time, who forwarded it, source channel etc... +FIXME, remove concept of meshid for now? optionally add to envelope later? +FIXME, the payload published on the topic, will include the message, and full information about arrival time, who forwarded it, source channel etc... Use a ServiceEnvelope protobuf. + +FIXME, use public mqtt servers, leave messages encrypted +FIXME, include testcase of trivial text message global mirroring +FIXME, possibly don't global mirror text messages - instead rely on matrix/riot? FIXME, figure out how channelids work FIXME, figure out rules for store and forward - #### 1.6.1.1. MESHID A unique ID for this mesh. There will be some sort of key exchange process so that the mesh ID can not be impersonated by other meshes. From c972197643340b8c8234bd1d36fe367a45b6eec1 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sun, 27 Dec 2020 16:58:32 +0800 Subject: [PATCH 2/2] fix #598 don't corrupt the heap when a TCP connection drops --- src/Observer.h | 9 +++++++++ src/esp32/WiFiServerAPI.cpp | 11 ++++++++--- src/mesh/PhoneAPI.cpp | 19 ++++++++++++------- src/mesh/PhoneAPI.h | 13 +++++++++---- 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/Observer.h b/src/Observer.h index 701495b38..85c40b1ea 100644 --- a/src/Observer.h +++ b/src/Observer.h @@ -16,6 +16,10 @@ template class Observer public: virtual ~Observer(); + /// Stop watching our current obserable + void unobserve(); + + /// Start watching a specified observable void observe(Observable *o); private: @@ -82,6 +86,11 @@ template class Observable }; template Observer::~Observer() +{ + unobserve(); +} + +template void Observer::unobserve() { if (observed) observed->removeObserver(this); diff --git a/src/esp32/WiFiServerAPI.cpp b/src/esp32/WiFiServerAPI.cpp index 632116bf3..3b11c2ae4 100644 --- a/src/esp32/WiFiServerAPI.cpp +++ b/src/esp32/WiFiServerAPI.cpp @@ -32,9 +32,14 @@ void WiFiServerAPI::loop() { if (client.connected()) { StreamAPI::loop(); - } else { - DEBUG_MSG("Client dropped connection, closing TCP server\n"); - delete this; + } 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(); } } diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 754f0d380..a0cad4273 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -7,22 +7,27 @@ #include #if FromRadio_size > MAX_TO_FROM_RADIO_SIZE - #error FromRadio is too big +#error FromRadio is too big #endif #if ToRadio_size > MAX_TO_FROM_RADIO_SIZE - #error ToRadio is too big +#error ToRadio is too big #endif -PhoneAPI::PhoneAPI() -{ -} +PhoneAPI::PhoneAPI() {} void PhoneAPI::init() { observe(&service.fromNumChanged); } +void PhoneAPI::close() { + unobserve(); + state = STATE_SEND_NOTHING; + isConnected = false; + onConnectionChanged(isConnected); +} + void PhoneAPI::checkConnectionTimeout() { if (isConnected) { @@ -102,7 +107,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf) if (!available()) { // DEBUG_MSG("getFromRadio, !available\n"); return 0; - } + } DEBUG_MSG("getFromRadio, state=%d\n", state); @@ -170,7 +175,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf) if (packetForPhone) { printPacket("phone downloaded packet", packetForPhone); - + // Encapsulate as a FromRadio packet fromRadioScratch.which_variant = FromRadio_packet_tag; fromRadioScratch.variant.packet = *packetForPhone; diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h index 129ecb5db..b895adc7e 100644 --- a/src/mesh/PhoneAPI.h +++ b/src/mesh/PhoneAPI.h @@ -21,7 +21,7 @@ class PhoneAPI : public Observer // FIXME, we shouldn't be inheriting from Observer, instead use CallbackObserver as a member { enum State { - STATE_LEGACY, // Temporary default state - until Android apps are all updated, uses the old BLE API + STATE_LEGACY, // (no longer used) old default state - until Android apps are all updated, uses the old BLE API STATE_SEND_NOTHING, // (Eventual) Initial state, don't send anything until the client starts asking for config STATE_SEND_MY_INFO, // send our my info record STATE_SEND_RADIO, @@ -31,7 +31,7 @@ class PhoneAPI STATE_SEND_PACKETS // send packets or debug strings }; - State state = STATE_LEGACY; + State state = STATE_SEND_NOTHING; /** * Each packet sent to the phone has an incrementing count @@ -53,14 +53,16 @@ class PhoneAPI /** the last msec we heard from the client on the other side of this link */ uint32_t lastContactMsec = 0; - bool isConnected = false; - public: 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(); + /** * Handle a ToRadio protobuf */ @@ -87,6 +89,9 @@ class PhoneAPI void handleSetRadio(const RadioConfig &r); protected: + /// Are we currently connected to a client? + bool isConnected = false; + /// Our fromradio packet while it is being assembled FromRadio fromRadioScratch;