Merge branch 'master' into static-buffer-gps

This commit is contained in:
Ben Meadors
2025-09-05 07:21:07 -05:00
committed by GitHub
2 changed files with 59 additions and 26 deletions

View File

@@ -833,16 +833,25 @@ void Power::readPowerStatus()
newStatus.notifyObservers(&powerStatus2); newStatus.notifyObservers(&powerStatus2);
#ifdef DEBUG_HEAP #ifdef DEBUG_HEAP
if (lastheap != memGet.getFreeHeap()) { if (lastheap != memGet.getFreeHeap()) {
std::string threadlist = "Threads running:"; // Use stack-allocated buffer to avoid heap allocations in monitoring code
char threadlist[256] = "Threads running:";
int threadlistLen = strlen(threadlist);
int running = 0; int running = 0;
for (int i = 0; i < MAX_THREADS; i++) { for (int i = 0; i < MAX_THREADS; i++) {
auto thread = concurrency::mainController.get(i); auto thread = concurrency::mainController.get(i);
if ((thread != nullptr) && (thread->enabled)) { if ((thread != nullptr) && (thread->enabled)) {
threadlist += vformat(" %s", thread->ThreadName.c_str()); // Use snprintf to safely append to stack buffer without heap allocation
int remaining = sizeof(threadlist) - threadlistLen - 1;
if (remaining > 0) {
int written = snprintf(threadlist + threadlistLen, remaining, " %s", thread->ThreadName.c_str());
if (written > 0 && written < remaining) {
threadlistLen += written;
}
}
running++; running++;
} }
} }
LOG_DEBUG(threadlist.c_str()); LOG_DEBUG(threadlist);
LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads", memGet.getFreeHeap(), memGet.getHeapSize(), LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads", memGet.getFreeHeap(), memGet.getHeapSize(),
memGet.getFreeHeap() - lastheap, running, concurrency::mainController.size(false)); memGet.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
lastheap = memGet.getFreeHeap(); lastheap = memGet.getFreeHeap();
@@ -856,15 +865,19 @@ void Power::readPowerStatus()
sprintf(mac, "!%02x%02x%02x%02x", dmac[2], dmac[3], dmac[4], dmac[5]); sprintf(mac, "!%02x%02x%02x%02x", dmac[2], dmac[3], dmac[4], dmac[5]);
auto newHeap = memGet.getFreeHeap(); auto newHeap = memGet.getFreeHeap();
std::string heapTopic = // Use stack-allocated buffers to avoid heap allocations in monitoring code
(*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + std::string("/2/heap/") + std::string(mac); char heapTopic[128];
std::string heapString = std::to_string(newHeap); snprintf(heapTopic, sizeof(heapTopic), "%s/2/heap/%s", (*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh"), mac);
mqtt->pubSub.publish(heapTopic.c_str(), heapString.c_str(), false); char heapString[16];
snprintf(heapString, sizeof(heapString), "%u", newHeap);
mqtt->pubSub.publish(heapTopic, heapString, false);
auto wifiRSSI = WiFi.RSSI(); auto wifiRSSI = WiFi.RSSI();
std::string wifiTopic = char wifiTopic[128];
(*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + std::string("/2/wifi/") + std::string(mac); snprintf(wifiTopic, sizeof(wifiTopic), "%s/2/wifi/%s", (*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh"), mac);
std::string wifiString = std::to_string(wifiRSSI); char wifiString[16];
mqtt->pubSub.publish(wifiTopic.c_str(), wifiString.c_str(), false); snprintf(wifiString, sizeof(wifiString), "%d", wifiRSSI);
mqtt->pubSub.publish(wifiTopic, wifiString, false);
} }
#endif #endif

View File

@@ -342,6 +342,11 @@ void handleFsBrowseStatic(HTTPRequest *req, HTTPResponse *res)
res->print(value->Stringify().c_str()); res->print(value->Stringify().c_str());
delete value; delete value;
// Clean up the fileList to prevent memory leak
for (auto *val : fileList) {
delete val;
}
} }
void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res) void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res)
@@ -610,33 +615,38 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
res->println("<pre>"); res->println("<pre>");
} }
// Helper lambda to create JSON array and clean up memory properly
auto createJSONArrayFromLog = [](uint32_t *logArray, int count) -> JSONValue * {
JSONArray tempArray;
for (int i = 0; i < count; i++) {
tempArray.push_back(new JSONValue((int)logArray[i]));
}
JSONValue *result = new JSONValue(tempArray);
// Clean up original array to prevent memory leak
for (auto *val : tempArray) {
delete val;
}
return result;
};
// data->airtime->tx_log // data->airtime->tx_log
JSONArray txLogValues;
uint32_t *logArray; uint32_t *logArray;
logArray = airTime->airtimeReport(TX_LOG); logArray = airTime->airtimeReport(TX_LOG);
for (int i = 0; i < airTime->getPeriodsToLog(); i++) { JSONValue *txLogJsonValue = createJSONArrayFromLog(logArray, airTime->getPeriodsToLog());
txLogValues.push_back(new JSONValue((int)logArray[i]));
}
// data->airtime->rx_log // data->airtime->rx_log
JSONArray rxLogValues;
logArray = airTime->airtimeReport(RX_LOG); logArray = airTime->airtimeReport(RX_LOG);
for (int i = 0; i < airTime->getPeriodsToLog(); i++) { JSONValue *rxLogJsonValue = createJSONArrayFromLog(logArray, airTime->getPeriodsToLog());
rxLogValues.push_back(new JSONValue((int)logArray[i]));
}
// data->airtime->rx_all_log // data->airtime->rx_all_log
JSONArray rxAllLogValues;
logArray = airTime->airtimeReport(RX_ALL_LOG); logArray = airTime->airtimeReport(RX_ALL_LOG);
for (int i = 0; i < airTime->getPeriodsToLog(); i++) { JSONValue *rxAllLogJsonValue = createJSONArrayFromLog(logArray, airTime->getPeriodsToLog());
rxAllLogValues.push_back(new JSONValue((int)logArray[i]));
}
// data->airtime // data->airtime
JSONObject jsonObjAirtime; JSONObject jsonObjAirtime;
jsonObjAirtime["tx_log"] = new JSONValue(txLogValues); jsonObjAirtime["tx_log"] = txLogJsonValue;
jsonObjAirtime["rx_log"] = new JSONValue(rxLogValues); jsonObjAirtime["rx_log"] = rxLogJsonValue;
jsonObjAirtime["rx_all_log"] = new JSONValue(rxAllLogValues); jsonObjAirtime["rx_all_log"] = rxAllLogJsonValue;
jsonObjAirtime["channel_utilization"] = new JSONValue(airTime->channelUtilizationPercent()); jsonObjAirtime["channel_utilization"] = new JSONValue(airTime->channelUtilizationPercent());
jsonObjAirtime["utilization_tx"] = new JSONValue(airTime->utilizationTXPercent()); jsonObjAirtime["utilization_tx"] = new JSONValue(airTime->utilizationTXPercent());
jsonObjAirtime["seconds_since_boot"] = new JSONValue(int(airTime->getSecondsSinceBoot())); jsonObjAirtime["seconds_since_boot"] = new JSONValue(int(airTime->getSecondsSinceBoot()));
@@ -765,6 +775,11 @@ void handleNodes(HTTPRequest *req, HTTPResponse *res)
JSONValue *value = new JSONValue(jsonObjOuter); JSONValue *value = new JSONValue(jsonObjOuter);
res->print(value->Stringify().c_str()); res->print(value->Stringify().c_str());
delete value; delete value;
// Clean up the nodesArray to prevent memory leak
for (auto *val : nodesArray) {
delete val;
}
} }
/* /*
@@ -955,5 +970,10 @@ void handleScanNetworks(HTTPRequest *req, HTTPResponse *res)
JSONValue *value = new JSONValue(jsonObjOuter); JSONValue *value = new JSONValue(jsonObjOuter);
res->print(value->Stringify().c_str()); res->print(value->Stringify().c_str());
delete value; delete value;
// Clean up the networkObjs to prevent memory leak
for (auto *val : networkObjs) {
delete val;
}
} }
#endif #endif