fix #598 don't corrupt the heap when a TCP connection drops

1.2-legacy
Kevin Hester 2020-12-27 16:58:32 +08:00
rodzic c06b7b2b48
commit c972197643
4 zmienionych plików z 38 dodań i 14 usunięć

Wyświetl plik

@ -16,6 +16,10 @@ template <class T> class Observer
public:
virtual ~Observer();
/// Stop watching our current obserable
void unobserve();
/// Start watching a specified observable
void observe(Observable<T> *o);
private:
@ -82,6 +86,11 @@ template <class T> class Observable
};
template <class T> Observer<T>::~Observer()
{
unobserve();
}
template <class T> void Observer<T>::unobserve()
{
if (observed)
observed->removeObserver(this);

Wyświetl plik

@ -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();
}
}

Wyświetl plik

@ -7,22 +7,27 @@
#include <assert.h>
#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;

Wyświetl plik

@ -21,7 +21,7 @@ class PhoneAPI
: public Observer<uint32_t> // 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;