prevent light sleep when modules are busy for more than one timer tick

This commit is contained in:
m1nl 2025-04-24 00:36:08 +02:00
parent 0b5030b436
commit 5d956d6bdc
10 changed files with 88 additions and 8 deletions

View File

@ -16,6 +16,7 @@
#include "SPILock.h"
#include "TypeConversions.h"
#include "main.h"
#include "sleep.h"
#include "xmodem.h"
#if FromRadio_size > MAX_TO_FROM_RADIO_SIZE
@ -35,10 +36,13 @@ PhoneAPI::PhoneAPI()
{
lastContactMsec = millis();
std::fill(std::begin(recentToRadioPacketIds), std::end(recentToRadioPacketIds), 0);
preflightSleepObserver.observe(&preflightSleep);
}
PhoneAPI::~PhoneAPI()
{
preflightSleepObserver.unobserve(&preflightSleep);
close();
}

View File

@ -172,4 +172,9 @@ class PhoneAPI
/// If the mesh service tells us fromNum has changed, tell the phone
virtual int onNotify(uint32_t newValue) override;
};
int preflightSleepCb(void *unused = NULL) { return available(); }
CallbackObserver<PhoneAPI, void *> preflightSleepObserver =
CallbackObserver<PhoneAPI, void *>(this, &PhoneAPI::preflightSleepCb);
};

View File

@ -1,6 +1,7 @@
#include "RadioLibInterface.h"
#include "MeshTypes.h"
#include "NodeDB.h"
#include "PowerFSM.h"
#include "PowerMon.h"
#include "SPILock.h"
#include "Throttle.h"
@ -245,6 +246,8 @@ currently active.
*/
void RadioLibInterface::onNotify(uint32_t notification)
{
powerFSM.trigger(EVENT_LORA_INTERRUPT);
switch (notification) {
case ISR_TX:
handleTransmitInterrupt();
@ -531,4 +534,4 @@ bool RadioLibInterface::startSend(meshtastic_MeshPacket *txp)
return res == RADIOLIB_ERR_NONE;
}
}
}

View File

@ -11,6 +11,7 @@
#include "mesh-pb-constants.h"
#include "meshUtils.h"
#include "modules/RoutingModule.h"
#include "sleep.h"
#if !MESHTASTIC_EXCLUDE_MQTT
#include "mqtt/MQTT.h"
#endif
@ -56,6 +57,13 @@ Router::Router() : concurrency::OSThread("Router"), fromRadioQueue(MAX_RX_FROMRA
// init Lockguard for crypt operations
assert(!cryptLock);
cryptLock = new concurrency::Lock();
preflightSleepObserver.observe(&preflightSleep);
}
Router::~Router()
{
preflightSleepObserver.unobserve(&preflightSleep);
}
/**
@ -65,6 +73,7 @@ Router::Router() : concurrency::OSThread("Router"), fromRadioQueue(MAX_RX_FROMRA
int32_t Router::runOnce()
{
meshtastic_MeshPacket *mp;
while ((mp = fromRadioQueue.dequeuePtr(0)) != NULL) {
// printPacket("handle fromRadioQ", mp);
perhapsHandleReceived(mp);
@ -150,6 +159,7 @@ void Router::abortSendAndNak(meshtastic_Routing_Error err, meshtastic_MeshPacket
void Router::setReceivedMessage()
{
// LOG_DEBUG("set interval to ASAP");
powerFSM.trigger(EVENT_WAKE_TIMER);
setInterval(0); // Run ASAP, so we can figure out our correct sleep time
runASAP = true;
}

View File

@ -29,6 +29,12 @@ class Router : protected concurrency::OSThread, protected PacketHistory
*/
Router();
/**
* Destructor
*
*/
~Router();
/**
* Currently we only allow one interface, that may change in the future
*/
@ -138,6 +144,10 @@ class Router : protected concurrency::OSThread, protected PacketHistory
/** Frees the provided packet, and generates a NAK indicating the specifed error while sending */
void abortSendAndNak(meshtastic_Routing_Error err, meshtastic_MeshPacket *p);
int preflightSleepCb(void *unused = NULL) { return !fromRadioQueue.isEmpty(); }
CallbackObserver<Router, void *> preflightSleepObserver = CallbackObserver<Router, void *>(this, &Router::preflightSleepCb);
};
enum DecodeState { DECODE_SUCCESS, DECODE_FAILURE, DECODE_FATAL };

View File

@ -97,6 +97,8 @@ void StreamAPI::writeStream()
void StreamAPI::emitTxBuffer(size_t len)
{
if (len != 0) {
powerFSM.trigger(EVENT_WAKE_TIMER);
txBuf[0] = START1;
txBuf[1] = START2;
txBuf[2] = (len >> 8) & 0xff;
@ -150,4 +152,4 @@ void StreamAPI::onConnectionChanged(bool connected)
// received a packet in a while
powerFSM.trigger(EVENT_SERIAL_DISCONNECTED);
}
}
}

View File

@ -148,7 +148,6 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res)
{
LOG_DEBUG("webAPI handleAPIv1FromRadio");
/*
@ -163,6 +162,8 @@ void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res)
// std::string paramAll = "all";
std::string valueAll;
powerFSM.trigger(EVENT_WEB_REQUEST);
// Status code is 200 OK by default.
res->setHeader("Content-Type", "application/x-protobuf");
res->setHeader("Access-Control-Allow-Origin", "*");
@ -207,6 +208,8 @@ void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res)
{
LOG_DEBUG("webAPI handleAPIv1ToRadio");
powerFSM.trigger(EVENT_WEB_REQUEST);
/*
For documentation, see:
https://meshtastic.org/docs/development/device/http-api
@ -316,6 +319,8 @@ JSONArray htmlListDir(const char *dirname, uint8_t levels)
void handleFsBrowseStatic(HTTPRequest *req, HTTPResponse *res)
{
powerFSM.trigger(EVENT_WEB_REQUEST);
res->setHeader("Content-Type", "application/json");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "GET");
@ -349,6 +354,8 @@ void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res)
ResourceParameters *params = req->getParams();
std::string paramValDelete;
powerFSM.trigger(EVENT_WEB_REQUEST);
res->setHeader("Content-Type", "application/json");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "DELETE");
@ -384,6 +391,9 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res)
ResourceParameters *params = req->getParams();
std::string parameter1;
powerFSM.trigger(EVENT_WEB_REQUEST);
// Print the first parameter value
if (params->getPathParameter(0, parameter1)) {
@ -469,8 +479,10 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res)
void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
{
LOG_DEBUG("Form Upload - Disable keep-alive");
powerFSM.trigger(EVENT_WEB_REQUEST);
res->setHeader("Connection", "close");
// First, we need to check the encoding of the form that we have received.
@ -597,6 +609,8 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
ResourceParameters *params = req->getParams();
std::string content;
powerFSM.trigger(EVENT_WEB_REQUEST);
if (!params->getQueryParameter("content", content)) {
content = "json";
}
@ -701,6 +715,8 @@ void handleNodes(HTTPRequest *req, HTTPResponse *res)
ResourceParameters *params = req->getParams();
std::string content;
powerFSM.trigger(EVENT_WEB_REQUEST);
if (!params->getQueryParameter("content", content)) {
content = "json";
}
@ -774,6 +790,8 @@ void handleHotspot(HTTPRequest *req, HTTPResponse *res)
{
LOG_INFO("Hotspot Request");
powerFSM.trigger(EVENT_WEB_REQUEST);
/*
If we don't do a redirect, be sure to return a "Success" message
otherwise iOS will have trouble detecting that the connection to the SoftAP worked.
@ -791,6 +809,8 @@ void handleHotspot(HTTPRequest *req, HTTPResponse *res)
void handleDeleteFsContent(HTTPRequest *req, HTTPResponse *res)
{
powerFSM.trigger(EVENT_WEB_REQUEST);
res->setHeader("Content-Type", "text/html");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "GET");
@ -808,6 +828,8 @@ void handleDeleteFsContent(HTTPRequest *req, HTTPResponse *res)
void handleAdmin(HTTPRequest *req, HTTPResponse *res)
{
powerFSM.trigger(EVENT_WEB_REQUEST);
res->setHeader("Content-Type", "text/html");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "GET");
@ -820,6 +842,8 @@ void handleAdmin(HTTPRequest *req, HTTPResponse *res)
void handleAdminSettings(HTTPRequest *req, HTTPResponse *res)
{
powerFSM.trigger(EVENT_WEB_REQUEST);
res->setHeader("Content-Type", "text/html");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "GET");
@ -842,6 +866,8 @@ void handleAdminSettings(HTTPRequest *req, HTTPResponse *res)
void handleAdminSettingsApply(HTTPRequest *req, HTTPResponse *res)
{
powerFSM.trigger(EVENT_WEB_REQUEST);
res->setHeader("Content-Type", "text/html");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "POST");
@ -854,6 +880,8 @@ void handleAdminSettingsApply(HTTPRequest *req, HTTPResponse *res)
void handleFs(HTTPRequest *req, HTTPResponse *res)
{
powerFSM.trigger(EVENT_WEB_REQUEST);
res->setHeader("Content-Type", "text/html");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "GET");
@ -866,6 +894,8 @@ void handleFs(HTTPRequest *req, HTTPResponse *res)
void handleRestart(HTTPRequest *req, HTTPResponse *res)
{
powerFSM.trigger(EVENT_WEB_REQUEST);
res->setHeader("Content-Type", "text/html");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "GET");
@ -879,6 +909,8 @@ void handleRestart(HTTPRequest *req, HTTPResponse *res)
void handleBlinkLED(HTTPRequest *req, HTTPResponse *res)
{
powerFSM.trigger(EVENT_WEB_REQUEST);
res->setHeader("Content-Type", "application/json");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "POST");
@ -917,6 +949,8 @@ void handleBlinkLED(HTTPRequest *req, HTTPResponse *res)
void handleScanNetworks(HTTPRequest *req, HTTPResponse *res)
{
powerFSM.trigger(EVENT_WEB_REQUEST);
res->setHeader("Content-Type", "application/json");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "GET");
@ -956,4 +990,4 @@ void handleScanNetworks(HTTPRequest *req, HTTPResponse *res)
res->print(value->Stringify().c_str());
delete value;
}
#endif
#endif

View File

@ -1,4 +1,7 @@
#pragma once
#define HTTP_API_SESSION_TIMEOUT_MS 5000
void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer);
// Declare some handler functions for the various URLs on the server
@ -33,5 +36,5 @@ class HttpAPI : public PhoneAPI
protected:
/// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected() override { return true; } // FIXME, be smarter about this
};
virtual bool checkIsConnected() override { return millis() - lastContactMsec < HTTP_API_SESSION_TIMEOUT_MS; }
};

View File

@ -536,6 +536,9 @@ bool EnvironmentTelemetryModule::getEnvironmentTelemetry(meshtastic_Telemetry *m
{
bool valid = true;
bool hasSensor = false;
powerFSM.trigger(EVENT_WAKE_TIMER); // ensure we're not light-sleeping
m->time = getTime();
m->which_variant = meshtastic_Telemetry_environment_metrics_tag;
m->variant.environment_metrics = meshtastic_EnvironmentMetrics_init_zero;
@ -721,6 +724,9 @@ meshtastic_MeshPacket *EnvironmentTelemetryModule::allocReply()
bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
{
meshtastic_Telemetry m = meshtastic_Telemetry_init_zero;
powerFSM.trigger(EVENT_WAKE_TIMER); // ensure we're not light-sleeping
m.which_variant = meshtastic_Telemetry_environment_metrics_tag;
m.time = getTime();
#ifdef T1000X_SENSOR_EN

View File

@ -190,6 +190,9 @@ bool PowerTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &m
bool PowerTelemetryModule::getPowerTelemetry(meshtastic_Telemetry *m)
{
bool valid = false;
powerFSM.trigger(EVENT_WAKE_TIMER); // ensure we're not light-sleeping
m->time = getTime();
m->which_variant = meshtastic_Telemetry_power_metrics_tag;