sforkowany z mirror/meshtastic-firmware
fix #598 don't corrupt the heap when a TCP connection drops
rodzic
c06b7b2b48
commit
c972197643
|
@ -16,6 +16,10 @@ template <class T> class Observer
|
||||||
public:
|
public:
|
||||||
virtual ~Observer();
|
virtual ~Observer();
|
||||||
|
|
||||||
|
/// Stop watching our current obserable
|
||||||
|
void unobserve();
|
||||||
|
|
||||||
|
/// Start watching a specified observable
|
||||||
void observe(Observable<T> *o);
|
void observe(Observable<T> *o);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -82,6 +86,11 @@ template <class T> class Observable
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T> Observer<T>::~Observer()
|
template <class T> Observer<T>::~Observer()
|
||||||
|
{
|
||||||
|
unobserve();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> void Observer<T>::unobserve()
|
||||||
{
|
{
|
||||||
if (observed)
|
if (observed)
|
||||||
observed->removeObserver(this);
|
observed->removeObserver(this);
|
||||||
|
|
|
@ -32,9 +32,14 @@ void WiFiServerAPI::loop()
|
||||||
{
|
{
|
||||||
if (client.connected()) {
|
if (client.connected()) {
|
||||||
StreamAPI::loop();
|
StreamAPI::loop();
|
||||||
} else {
|
} else if(isConnected) {
|
||||||
DEBUG_MSG("Client dropped connection, closing TCP server\n");
|
// If our API link was up, shut it down
|
||||||
delete this;
|
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,22 +7,27 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#if FromRadio_size > MAX_TO_FROM_RADIO_SIZE
|
#if FromRadio_size > MAX_TO_FROM_RADIO_SIZE
|
||||||
#error FromRadio is too big
|
#error FromRadio is too big
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ToRadio_size > MAX_TO_FROM_RADIO_SIZE
|
#if ToRadio_size > MAX_TO_FROM_RADIO_SIZE
|
||||||
#error ToRadio is too big
|
#error ToRadio is too big
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PhoneAPI::PhoneAPI()
|
PhoneAPI::PhoneAPI() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void PhoneAPI::init()
|
void PhoneAPI::init()
|
||||||
{
|
{
|
||||||
observe(&service.fromNumChanged);
|
observe(&service.fromNumChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhoneAPI::close() {
|
||||||
|
unobserve();
|
||||||
|
state = STATE_SEND_NOTHING;
|
||||||
|
isConnected = false;
|
||||||
|
onConnectionChanged(isConnected);
|
||||||
|
}
|
||||||
|
|
||||||
void PhoneAPI::checkConnectionTimeout()
|
void PhoneAPI::checkConnectionTimeout()
|
||||||
{
|
{
|
||||||
if (isConnected) {
|
if (isConnected) {
|
||||||
|
@ -102,7 +107,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||||
if (!available()) {
|
if (!available()) {
|
||||||
// DEBUG_MSG("getFromRadio, !available\n");
|
// DEBUG_MSG("getFromRadio, !available\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_MSG("getFromRadio, state=%d\n", state);
|
DEBUG_MSG("getFromRadio, state=%d\n", state);
|
||||||
|
|
||||||
|
@ -170,7 +175,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||||
if (packetForPhone) {
|
if (packetForPhone) {
|
||||||
|
|
||||||
printPacket("phone downloaded packet", packetForPhone);
|
printPacket("phone downloaded packet", packetForPhone);
|
||||||
|
|
||||||
// Encapsulate as a FromRadio packet
|
// Encapsulate as a FromRadio packet
|
||||||
fromRadioScratch.which_variant = FromRadio_packet_tag;
|
fromRadioScratch.which_variant = FromRadio_packet_tag;
|
||||||
fromRadioScratch.variant.packet = *packetForPhone;
|
fromRadioScratch.variant.packet = *packetForPhone;
|
||||||
|
|
|
@ -21,7 +21,7 @@ class PhoneAPI
|
||||||
: public Observer<uint32_t> // FIXME, we shouldn't be inheriting from Observer, instead use CallbackObserver as a member
|
: public Observer<uint32_t> // FIXME, we shouldn't be inheriting from Observer, instead use CallbackObserver as a member
|
||||||
{
|
{
|
||||||
enum State {
|
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_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_MY_INFO, // send our my info record
|
||||||
STATE_SEND_RADIO,
|
STATE_SEND_RADIO,
|
||||||
|
@ -31,7 +31,7 @@ class PhoneAPI
|
||||||
STATE_SEND_PACKETS // send packets or debug strings
|
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
|
* 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 */
|
/** the last msec we heard from the client on the other side of this link */
|
||||||
uint32_t lastContactMsec = 0;
|
uint32_t lastContactMsec = 0;
|
||||||
|
|
||||||
bool isConnected = false;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PhoneAPI();
|
PhoneAPI();
|
||||||
|
|
||||||
/// Do late init that can't happen at constructor time
|
/// Do late init that can't happen at constructor time
|
||||||
virtual void init();
|
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
|
* Handle a ToRadio protobuf
|
||||||
*/
|
*/
|
||||||
|
@ -87,6 +89,9 @@ class PhoneAPI
|
||||||
void handleSetRadio(const RadioConfig &r);
|
void handleSetRadio(const RadioConfig &r);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/// Are we currently connected to a client?
|
||||||
|
bool isConnected = false;
|
||||||
|
|
||||||
/// Our fromradio packet while it is being assembled
|
/// Our fromradio packet while it is being assembled
|
||||||
FromRadio fromRadioScratch;
|
FromRadio fromRadioScratch;
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue