From fb75410e535350a5042bf48ddb21652b4137a3aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 21 Jul 2026 01:37:13 +0200 Subject: [PATCH] Null-check packet allocations in allocForSending and its callers (#11086) * Null-check packet allocations in allocForSending and its callers Sibling of 0ae44d701. * Null-check allocDataProtobuf, allocAckNak and allocErrorResponse callers Second tier of the same nullable contract. * Keep telemetry sleep scheduling on allocation failure Allocation failure now marks the telemetry invalid instead of returning early, so power-saving SENSOR nodes still arm deep sleep. --- .../InkHUD/Applets/System/Menu/MenuApplet.cpp | 2 + src/mesh/MeshModule.cpp | 2 + src/mesh/ProtobufModule.h | 2 + src/mesh/Router.cpp | 2 + src/mesh/SinglePortModule.h | 2 + src/modules/AdminModule.cpp | 24 ++++++++ src/modules/CannedMessageModule.cpp | 2 + src/modules/DetectionSensorModule.cpp | 8 +++ src/modules/DropzoneModule.cpp | 2 + src/modules/KeyVerificationModule.cpp | 4 ++ src/modules/NeighborInfoModule.cpp | 2 + src/modules/PositionModule.cpp | 4 ++ src/modules/RangeTestModule.cpp | 2 + src/modules/ReplyBotModule.cpp | 2 + src/modules/ReplyModule.cpp | 4 +- src/modules/RoutingModule.cpp | 2 + src/modules/SerialModule.cpp | 4 ++ src/modules/SerialModule.h | 2 + src/modules/StatusMessageModule.cpp | 2 + src/modules/StoreForwardModule.cpp | 6 ++ src/modules/Telemetry/AirQualityTelemetry.cpp | 58 ++++++++++--------- src/modules/Telemetry/DeviceTelemetry.cpp | 4 ++ .../Telemetry/EnvironmentTelemetry.cpp | 56 +++++++++--------- src/modules/Telemetry/HealthTelemetry.cpp | 36 +++++++----- src/modules/Telemetry/HostMetrics.cpp | 2 + src/modules/Telemetry/PowerTelemetry.cpp | 36 +++++++----- src/modules/esp32/AudioModule.cpp | 2 + src/modules/esp32/PaxcounterModule.cpp | 2 + src/modules/games/GamesModule.cpp | 2 + src/mqtt/MQTT.cpp | 2 + 30 files changed, 194 insertions(+), 86 deletions(-) diff --git a/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.cpp b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.cpp index ac1fd1e73..005f60da5 100644 --- a/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.cpp +++ b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.cpp @@ -2614,6 +2614,8 @@ uint16_t InkHUD::MenuApplet::getSystemInfoPanelHeight() void InkHUD::MenuApplet::sendText(NodeNum dest, ChannelIndex channel, const char *message) { meshtastic_MeshPacket *p = router->allocForSending(); + if (!p) + return; p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP; p->to = dest; p->channel = channel; diff --git a/src/mesh/MeshModule.cpp b/src/mesh/MeshModule.cpp index a4acea7f1..aaed129f8 100644 --- a/src/mesh/MeshModule.cpp +++ b/src/mesh/MeshModule.cpp @@ -57,6 +57,8 @@ meshtastic_MeshPacket *MeshModule::allocAckNak(meshtastic_Routing_Error err, Nod // So we manually call pb_encode_to_bytes and specify routing port number // auto p = allocDataProtobuf(c); meshtastic_MeshPacket *p = router->allocForSending(); + if (!p) + return nullptr; p->decoded.portnum = meshtastic_PortNum_ROUTING_APP; p->decoded.payload.size = pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), &meshtastic_Routing_msg, &c); diff --git a/src/mesh/ProtobufModule.h b/src/mesh/ProtobufModule.h index 42d80d5d6..1d1441c4d 100644 --- a/src/mesh/ProtobufModule.h +++ b/src/mesh/ProtobufModule.h @@ -44,6 +44,8 @@ template class ProtobufModule : protected SinglePortModule { // Update our local node info with our position (even if we don't decide to update anyone else) meshtastic_MeshPacket *p = allocDataPacket(); + if (!p) + return nullptr; p->decoded.payload.size = pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), fields, &payload); diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index 7b78b763f..cba2d9868 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -194,6 +194,8 @@ PacketId generatePacketId() meshtastic_MeshPacket *Router::allocForSending() { meshtastic_MeshPacket *p = packetPool.allocZeroed(); + if (!p) + return nullptr; p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // Assume payload is decoded at start. p->from = nodeDB->getNodeNum(); diff --git a/src/mesh/SinglePortModule.h b/src/mesh/SinglePortModule.h index e43de09d1..67444329a 100644 --- a/src/mesh/SinglePortModule.h +++ b/src/mesh/SinglePortModule.h @@ -32,6 +32,8 @@ class SinglePortModule : public MeshModule { // Update our local node info with our position (even if we don't decide to update anyone else) meshtastic_MeshPacket *p = router->allocForSending(); + if (!p) + return nullptr; p->decoded.portnum = ourPortNum; return p; diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index d3389ad13..165f43638 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -1417,6 +1417,9 @@ void AdminModule::handleGetOwner(const meshtastic_MeshPacket &req) res.which_payload_variant = meshtastic_AdminMessage_get_owner_response_tag; setPassKey(&res); myReply = allocDataProtobuf(res); + if (!myReply) { + return; + } if (req.pki_encrypted) { myReply->pki_encrypted = true; } @@ -1500,6 +1503,9 @@ void AdminModule::handleGetConfig(const meshtastic_MeshPacket &req, const uint32 res.which_payload_variant = meshtastic_AdminMessage_get_config_response_tag; setPassKey(&res); myReply = allocDataProtobuf(res); + if (!myReply) { + return; + } if (req.pki_encrypted) { myReply->pki_encrypted = true; } @@ -1609,6 +1615,9 @@ void AdminModule::handleGetModuleConfig(const meshtastic_MeshPacket &req, const res.which_payload_variant = meshtastic_AdminMessage_get_module_config_response_tag; setPassKey(&res); myReply = allocDataProtobuf(res); + if (!myReply) { + return; + } if (req.pki_encrypted) { myReply->pki_encrypted = true; } @@ -1636,6 +1645,9 @@ void AdminModule::handleGetNodeRemoteHardwarePins(const meshtastic_MeshPacket &r } setPassKey(&r); myReply = allocDataProtobuf(r); + if (!myReply) { + return; + } if (req.pki_encrypted) { myReply->pki_encrypted = true; } @@ -1655,6 +1667,9 @@ void AdminModule::handleGetDeviceMetadata(const meshtastic_MeshPacket &req) r.which_payload_variant = meshtastic_AdminMessage_get_device_metadata_response_tag; setPassKey(&r); myReply = allocDataProtobuf(r); + if (!myReply) { + return; + } if (req.pki_encrypted) { myReply->pki_encrypted = true; } @@ -1730,6 +1745,9 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r r.which_payload_variant = meshtastic_AdminMessage_get_device_connection_status_response_tag; setPassKey(&r); myReply = allocDataProtobuf(r); + if (!myReply) { + return; + } if (req.pki_encrypted) { myReply->pki_encrypted = true; } @@ -1744,6 +1762,9 @@ void AdminModule::handleGetChannel(const meshtastic_MeshPacket &req, uint32_t ch r.which_payload_variant = meshtastic_AdminMessage_get_channel_response_tag; setPassKey(&r); myReply = allocDataProtobuf(r); + if (!myReply) { + return; + } if (req.pki_encrypted) { myReply->pki_encrypted = true; } @@ -1756,6 +1777,9 @@ void AdminModule::handleGetDeviceUIConfig(const meshtastic_MeshPacket &req) r.which_payload_variant = meshtastic_AdminMessage_get_ui_config_response_tag; r.get_ui_config_response = uiconfig; myReply = allocDataProtobuf(r); + if (!myReply) { + return; + } if (req.pki_encrypted) { myReply->pki_encrypted = true; } diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index dada48193..71858009e 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -1022,6 +1022,8 @@ void CannedMessageModule::sendText(NodeNum dest, ChannelIndex channel, const cha lastDestSet = true; meshtastic_MeshPacket *p = allocDataPacket(); + if (!p) + return; p->to = dest; p->channel = channel; p->want_ack = true; diff --git a/src/modules/DetectionSensorModule.cpp b/src/modules/DetectionSensorModule.cpp index 7e33c7a75..b17db136f 100644 --- a/src/modules/DetectionSensorModule.cpp +++ b/src/modules/DetectionSensorModule.cpp @@ -131,6 +131,10 @@ void DetectionSensorModule::sendDetectionMessage() char *message = new char[40]; sprintf(message, "%s detected", moduleConfig.detection_sensor.name); meshtastic_MeshPacket *p = allocDataPacket(); + if (!p) { + delete[] message; + return; + } p->want_ack = false; p->decoded.payload.size = strlen(message); memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size); @@ -153,6 +157,10 @@ void DetectionSensorModule::sendCurrentStateMessage(bool state) char *message = new char[40]; sprintf(message, "%s state: %i", moduleConfig.detection_sensor.name, state); meshtastic_MeshPacket *p = allocDataPacket(); + if (!p) { + delete[] message; + return; + } p->want_ack = false; p->decoded.payload.size = strlen(message); memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size); diff --git a/src/modules/DropzoneModule.cpp b/src/modules/DropzoneModule.cpp index 4b8f2fec8..2340f31f2 100644 --- a/src/modules/DropzoneModule.cpp +++ b/src/modules/DropzoneModule.cpp @@ -68,6 +68,8 @@ meshtastic_MeshPacket *DropzoneModule::sendConditions() // the dropzone is open auto dropzoneStatus = analogRead(A1) < 100 ? "OPEN" : "CLOSED"; auto reply = allocDataPacket(); + if (!reply) + return nullptr; auto node = nodeDB->getMeshNode(nodeDB->getNodeNum()); if (sensor.hasSensor()) { diff --git a/src/modules/KeyVerificationModule.cpp b/src/modules/KeyVerificationModule.cpp index ca57bf816..f1483e90e 100644 --- a/src/modules/KeyVerificationModule.cpp +++ b/src/modules/KeyVerificationModule.cpp @@ -169,6 +169,8 @@ bool KeyVerificationModule::sendInitialRequest(NodeNum remoteNode) KeyVerification.hash1.size = 32; memcpy(KeyVerification.hash1.bytes, owner.public_key.bytes, 32); meshtastic_MeshPacket *p = allocDataProtobuf(KeyVerification); + if (!p) + return false; p->to = remoteNode; p->channel = 0; // Only request PKI when we already hold the destination's key. Otherwise this first message goes out @@ -325,6 +327,8 @@ void KeyVerificationModule::processSecurityNumber(uint32_t incomingNumber) KeyVerification.hash1.size = 32; memcpy(KeyVerification.hash1.bytes, hash1, 32); meshtastic_MeshPacket *p = allocDataProtobuf(KeyVerification); + if (!p) + return; p->to = currentRemoteNode; p->channel = 0; p->pki_encrypted = true; diff --git a/src/modules/NeighborInfoModule.cpp b/src/modules/NeighborInfoModule.cpp index a626bbcaa..f42194a81 100644 --- a/src/modules/NeighborInfoModule.cpp +++ b/src/modules/NeighborInfoModule.cpp @@ -110,6 +110,8 @@ void NeighborInfoModule::sendNeighborInfo(NodeNum dest, bool wantReplies) // only send neighbours if we have some to send if (neighborInfo.neighbors_count > 0) { meshtastic_MeshPacket *p = allocDataProtobuf(neighborInfo); + if (!p) + return; p->to = dest; p->decoded.want_response = wantReplies; p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index 18931da12..40055006a 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -292,6 +292,8 @@ meshtastic_MeshPacket *PositionModule::allocAtakPli() { LOG_INFO("Send TAK V2 PLI packet"); meshtastic_MeshPacket *mp = allocDataPacket(); + if (!mp) + return nullptr; mp->decoded.portnum = meshtastic_PortNum_ATAK_PLUGIN_V2; meshtastic_TAKPacketV2 takPacket = meshtastic_TAKPacketV2_init_zero; @@ -572,6 +574,8 @@ int32_t PositionModule::runOnce() void PositionModule::sendLostAndFoundText() { meshtastic_MeshPacket *p = allocDataPacket(); + if (!p) + return; p->to = NODENUM_BROADCAST; char message[128]; int written = snprintf(message, sizeof(message), "🚨I'm lost! Lat / Lon: %f, %f\a", (lastGpsLatitude * 1e-7), diff --git a/src/modules/RangeTestModule.cpp b/src/modules/RangeTestModule.cpp index a02f0594e..dad748699 100644 --- a/src/modules/RangeTestModule.cpp +++ b/src/modules/RangeTestModule.cpp @@ -114,6 +114,8 @@ int32_t RangeTestModule::runOnce() void RangeTestModuleRadio::sendPayload(NodeNum dest, bool wantReplies) { meshtastic_MeshPacket *p = allocDataPacket(); + if (!p) + return; p->to = dest; p->decoded.want_response = wantReplies; p->hop_limit = 0; diff --git a/src/modules/ReplyBotModule.cpp b/src/modules/ReplyBotModule.cpp index 3f8788735..52934c800 100644 --- a/src/modules/ReplyBotModule.cpp +++ b/src/modules/ReplyBotModule.cpp @@ -168,6 +168,8 @@ void ReplyBotModule::sendDm(const meshtastic_MeshPacket &rx, const char *text) if (!text) return; meshtastic_MeshPacket *p = allocDataPacket(); + if (!p) + return; p->to = rx.from; p->channel = rx.channel; p->want_ack = false; diff --git a/src/modules/ReplyModule.cpp b/src/modules/ReplyModule.cpp index c48b16d53..7a97c0c68 100644 --- a/src/modules/ReplyModule.cpp +++ b/src/modules/ReplyModule.cpp @@ -16,7 +16,9 @@ meshtastic_MeshPacket *ReplyModule::allocReply() #endif const char *replyStr = "Message Received"; - auto reply = allocDataPacket(); // Allocate a packet for sending + auto reply = allocDataPacket(); // Allocate a packet for sending + if (!reply) + return nullptr; reply->decoded.payload.size = strlen(replyStr); // You must specify how many bytes are in the reply memcpy(reply->decoded.payload.bytes, replyStr, reply->decoded.payload.size); diff --git a/src/modules/RoutingModule.cpp b/src/modules/RoutingModule.cpp index aba0751f3..1ce7c4502 100644 --- a/src/modules/RoutingModule.cpp +++ b/src/modules/RoutingModule.cpp @@ -51,6 +51,8 @@ void RoutingModule::sendAckNak(meshtastic_Routing_Error err, NodeNum to, PacketI bool ackWantsAck) { auto p = allocAckNak(err, to, idFrom, chIndex, hopLimit); + if (!p) + return; // Allow the caller to set want_ack on this ACK packet if it's important that the ACK be delivered reliably p->want_ack = ackWantsAck; diff --git a/src/modules/SerialModule.cpp b/src/modules/SerialModule.cpp index aab79ffd5..b3b42a37d 100644 --- a/src/modules/SerialModule.cpp +++ b/src/modules/SerialModule.cpp @@ -314,6 +314,8 @@ int32_t SerialModule::runOnce() void SerialModule::sendTelemetry(meshtastic_Telemetry m) { meshtastic_MeshPacket *p = router->allocForSending(); + if (!p) + return; p->decoded.portnum = meshtastic_PortNum_TELEMETRY_APP; p->decoded.payload.size = pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), &meshtastic_Telemetry_msg, &m); @@ -350,6 +352,8 @@ void SerialModuleRadio::sendPayload(NodeNum dest, bool wantReplies) { const meshtastic_Channel *ch = (boundChannel != NULL) ? &channels.getByName(boundChannel) : NULL; meshtastic_MeshPacket *p = allocReply(); + if (!p) + return; p->to = dest; if (ch != NULL) { p->channel = ch->index; diff --git a/src/modules/SerialModule.h b/src/modules/SerialModule.h index dbe4f75db..768feeec6 100644 --- a/src/modules/SerialModule.h +++ b/src/modules/SerialModule.h @@ -71,6 +71,8 @@ class SerialModuleRadio : public MeshModule { // Update our local node info with our position (even if we don't decide to update anyone else) meshtastic_MeshPacket *p = router->allocForSending(); + if (!p) + return nullptr; p->decoded.portnum = ourPortNum; return p; diff --git a/src/modules/StatusMessageModule.cpp b/src/modules/StatusMessageModule.cpp index 2f05517f3..bf4badc4b 100644 --- a/src/modules/StatusMessageModule.cpp +++ b/src/modules/StatusMessageModule.cpp @@ -15,6 +15,8 @@ int32_t StatusMessageModule::runOnce() strncpy(ourStatus.status, moduleConfig.statusmessage.node_status, sizeof(ourStatus.status)); ourStatus.status[sizeof(ourStatus.status) - 1] = '\0'; // ensure null termination meshtastic_MeshPacket *p = allocDataPacket(); + if (!p) + return 1000 * 12 * 60 * 60; p->decoded.payload.size = pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), meshtastic_StatusMessage_fields, &ourStatus); p->to = NODENUM_BROADCAST; diff --git a/src/modules/StoreForwardModule.cpp b/src/modules/StoreForwardModule.cpp index 3254d11a3..de1d6865c 100644 --- a/src/modules/StoreForwardModule.cpp +++ b/src/modules/StoreForwardModule.cpp @@ -248,6 +248,8 @@ meshtastic_MeshPacket *StoreForwardModule::preparePayload(NodeNum dest, uint32_t (this->packetHistory[i].to == NODENUM_BROADCAST || this->packetHistory[i].to == dest)) { meshtastic_MeshPacket *p = allocDataPacket(); + if (!p) + return nullptr; p->to = local ? this->packetHistory[i].to : dest; // PhoneAPI can handle original `to` p->from = this->packetHistory[i].from; @@ -304,6 +306,8 @@ meshtastic_MeshPacket *StoreForwardModule::preparePayload(NodeNum dest, uint32_t void StoreForwardModule::sendMessage(NodeNum dest, const meshtastic_StoreAndForward &payload) { meshtastic_MeshPacket *p = allocDataProtobuf(payload); + if (!p) + return; p->to = dest; @@ -340,6 +344,8 @@ void StoreForwardModule::sendMessage(NodeNum dest, meshtastic_StoreAndForward_Re void StoreForwardModule::sendErrorTextMessage(NodeNum dest, bool want_response) { meshtastic_MeshPacket *pr = allocDataPacket(); + if (!pr) + return; pr->to = dest; pr->priority = meshtastic_MeshPacket_Priority_BACKGROUND; pr->want_ack = false; diff --git a/src/modules/Telemetry/AirQualityTelemetry.cpp b/src/modules/Telemetry/AirQualityTelemetry.cpp index 7ab0ed3d4..9ea8d9e39 100644 --- a/src/modules/Telemetry/AirQualityTelemetry.cpp +++ b/src/modules/Telemetry/AirQualityTelemetry.cpp @@ -464,35 +464,39 @@ bool AirQualityTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) } meshtastic_MeshPacket *p = allocDataProtobuf(m); - p->to = dest; - p->decoded.want_response = false; - if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR) - p->priority = meshtastic_MeshPacket_Priority_RELIABLE; - else - p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; - - // release previous packet before occupying a new spot - if (lastMeasurementPacket != nullptr) - packetPool.release(lastMeasurementPacket); - - lastMeasurementPacket = packetPool.allocCopy(*p); - if (phoneOnly) { - LOG_INFO("Sending packet to phone"); - service->sendToPhone(p); + if (!p) { + validTelemetry = false; } else { - LOG_INFO("Sending packet to mesh"); - service->sendToMesh(p, RX_SRC_LOCAL, true); + p->to = dest; + p->decoded.want_response = false; + if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR) + p->priority = meshtastic_MeshPacket_Priority_RELIABLE; + else + p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; - if (isPowerSavingSensor()) { - meshtastic_ClientNotification *notification = clientNotificationPool.allocZeroed(); - if (notification) { - notification->level = meshtastic_LogRecord_Level_INFO; - notification->time = getValidTime(RTCQualityFromNet); - sprintf(notification->message, "Sending telemetry and sleeping for %us interval in a moment", - Default::getConfiguredOrDefaultMs(moduleConfig.telemetry.air_quality_interval, - default_telemetry_broadcast_interval_secs) / - 1000U); - service->sendClientNotification(notification); + // release previous packet before occupying a new spot + if (lastMeasurementPacket != nullptr) + packetPool.release(lastMeasurementPacket); + + lastMeasurementPacket = packetPool.allocCopy(*p); + if (phoneOnly) { + LOG_INFO("Sending packet to phone"); + service->sendToPhone(p); + } else { + LOG_INFO("Sending packet to mesh"); + service->sendToMesh(p, RX_SRC_LOCAL, true); + + if (isPowerSavingSensor()) { + meshtastic_ClientNotification *notification = clientNotificationPool.allocZeroed(); + if (notification) { + notification->level = meshtastic_LogRecord_Level_INFO; + notification->time = getValidTime(RTCQualityFromNet); + sprintf(notification->message, "Sending telemetry and sleeping for %us interval in a moment", + Default::getConfiguredOrDefaultMs(moduleConfig.telemetry.air_quality_interval, + default_telemetry_broadcast_interval_secs) / + 1000U); + service->sendClientNotification(notification); + } } } } diff --git a/src/modules/Telemetry/DeviceTelemetry.cpp b/src/modules/Telemetry/DeviceTelemetry.cpp index d8f17963d..7ae6ac615 100644 --- a/src/modules/Telemetry/DeviceTelemetry.cpp +++ b/src/modules/Telemetry/DeviceTelemetry.cpp @@ -172,6 +172,8 @@ meshtastic_Telemetry DeviceTelemetryModule::getLocalStatsTelemetry() void DeviceTelemetryModule::sendLocalStatsToPhone() { meshtastic_MeshPacket *p = allocDataProtobuf(getLocalStatsTelemetry()); + if (!p) + return; p->to = NODENUM_BROADCAST; p->decoded.want_response = false; p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; @@ -191,6 +193,8 @@ bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) meshtastic_MeshPacket *p = allocDataProtobuf(telemetry); DEBUG_HEAP_AFTER("DeviceTelemetryModule::sendTelemetry", p); + if (!p) + return false; p->to = dest; p->decoded.want_response = false; p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 63273239d..659ed3278 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -661,34 +661,38 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) m.variant.environment_metrics.soil_moisture); meshtastic_MeshPacket *p = allocDataProtobuf(m); - p->to = dest; - p->decoded.want_response = false; - if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR) - p->priority = meshtastic_MeshPacket_Priority_RELIABLE; - else - p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; - // release previous packet before occupying a new spot - if (lastMeasurementPacket != nullptr) - packetPool.release(lastMeasurementPacket); - - lastMeasurementPacket = packetPool.allocCopy(*p); - if (phoneOnly) { - LOG_INFO("Send packet to phone"); - service->sendToPhone(p); + if (!p) { + validTelemetry = false; } else { - LOG_INFO("Send packet to mesh"); - service->sendToMesh(p, RX_SRC_LOCAL, true); + p->to = dest; + p->decoded.want_response = false; + if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR) + p->priority = meshtastic_MeshPacket_Priority_RELIABLE; + else + p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; + // release previous packet before occupying a new spot + if (lastMeasurementPacket != nullptr) + packetPool.release(lastMeasurementPacket); - if (isPowerSavingSensor()) { - meshtastic_ClientNotification *notification = clientNotificationPool.allocZeroed(); - if (notification) { - notification->level = meshtastic_LogRecord_Level_INFO; - notification->time = getValidTime(RTCQualityFromNet); - sprintf(notification->message, "Sending telemetry and sleeping for %us interval in a moment", - Default::getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval, - default_telemetry_broadcast_interval_secs) / - 1000U); - service->sendClientNotification(notification); + lastMeasurementPacket = packetPool.allocCopy(*p); + if (phoneOnly) { + LOG_INFO("Send packet to phone"); + service->sendToPhone(p); + } else { + LOG_INFO("Send packet to mesh"); + service->sendToMesh(p, RX_SRC_LOCAL, true); + + if (isPowerSavingSensor()) { + meshtastic_ClientNotification *notification = clientNotificationPool.allocZeroed(); + if (notification) { + notification->level = meshtastic_LogRecord_Level_INFO; + notification->time = getValidTime(RTCQualityFromNet); + sprintf(notification->message, "Sending telemetry and sleeping for %us interval in a moment", + Default::getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval, + default_telemetry_broadcast_interval_secs) / + 1000U); + service->sendClientNotification(notification); + } } } } diff --git a/src/modules/Telemetry/HealthTelemetry.cpp b/src/modules/Telemetry/HealthTelemetry.cpp index f68c92e1b..944bc4db4 100644 --- a/src/modules/Telemetry/HealthTelemetry.cpp +++ b/src/modules/Telemetry/HealthTelemetry.cpp @@ -248,23 +248,27 @@ bool HealthTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) sensor_read_error_count = 0; meshtastic_MeshPacket *p = allocDataProtobuf(m); - p->to = dest; - p->decoded.want_response = false; - if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR) - p->priority = meshtastic_MeshPacket_Priority_RELIABLE; - else - p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; - // release previous packet before occupying a new spot - if (lastMeasurementPacket != nullptr) - packetPool.release(lastMeasurementPacket); - - lastMeasurementPacket = packetPool.allocCopy(*p); - if (phoneOnly) { - LOG_INFO("Send packet to phone"); - service->sendToPhone(p); + if (!p) { + validTelemetry = false; } else { - LOG_INFO("Send packet to mesh"); - service->sendToMesh(p, RX_SRC_LOCAL, true); + p->to = dest; + p->decoded.want_response = false; + if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR) + p->priority = meshtastic_MeshPacket_Priority_RELIABLE; + else + p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; + // release previous packet before occupying a new spot + if (lastMeasurementPacket != nullptr) + packetPool.release(lastMeasurementPacket); + + lastMeasurementPacket = packetPool.allocCopy(*p); + if (phoneOnly) { + LOG_INFO("Send packet to phone"); + service->sendToPhone(p); + } else { + LOG_INFO("Send packet to mesh"); + service->sendToMesh(p, RX_SRC_LOCAL, true); + } } } diff --git a/src/modules/Telemetry/HostMetrics.cpp b/src/modules/Telemetry/HostMetrics.cpp index 577132006..a9490bc10 100644 --- a/src/modules/Telemetry/HostMetrics.cpp +++ b/src/modules/Telemetry/HostMetrics.cpp @@ -128,6 +128,8 @@ bool HostMetricsModule::sendMetrics() // telemetry.variant.host_metrics.has_user_string ? telemetry.variant.host_metrics.user_string : ""); meshtastic_MeshPacket *p = allocDataProtobuf(telemetry); + if (!p) + return false; p->to = NODENUM_BROADCAST; p->decoded.want_response = false; p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; diff --git a/src/modules/Telemetry/PowerTelemetry.cpp b/src/modules/Telemetry/PowerTelemetry.cpp index 816f02898..23ef56ba8 100644 --- a/src/modules/Telemetry/PowerTelemetry.cpp +++ b/src/modules/Telemetry/PowerTelemetry.cpp @@ -275,23 +275,27 @@ bool PowerTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) sensor_read_error_count = 0; meshtastic_MeshPacket *p = allocDataProtobuf(m); - p->to = dest; - p->decoded.want_response = false; - if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR) - p->priority = meshtastic_MeshPacket_Priority_RELIABLE; - else - p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; - // release previous packet before occupying a new spot - if (lastMeasurementPacket != nullptr) - packetPool.release(lastMeasurementPacket); - - lastMeasurementPacket = packetPool.allocCopy(*p); - if (phoneOnly) { - LOG_INFO("Send packet to phone"); - service->sendToPhone(p); + if (!p) { + validTelemetry = false; } else { - LOG_INFO("Send packet to mesh"); - service->sendToMesh(p, RX_SRC_LOCAL, true); + p->to = dest; + p->decoded.want_response = false; + if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR) + p->priority = meshtastic_MeshPacket_Priority_RELIABLE; + else + p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; + // release previous packet before occupying a new spot + if (lastMeasurementPacket != nullptr) + packetPool.release(lastMeasurementPacket); + + lastMeasurementPacket = packetPool.allocCopy(*p); + if (phoneOnly) { + LOG_INFO("Send packet to phone"); + service->sendToPhone(p); + } else { + LOG_INFO("Send packet to mesh"); + service->sendToMesh(p, RX_SRC_LOCAL, true); + } } } diff --git a/src/modules/esp32/AudioModule.cpp b/src/modules/esp32/AudioModule.cpp index 815e426a2..0dc9832f3 100644 --- a/src/modules/esp32/AudioModule.cpp +++ b/src/modules/esp32/AudioModule.cpp @@ -258,6 +258,8 @@ bool AudioModule::shouldDraw() void AudioModule::sendPayload(NodeNum dest, bool wantReplies) { meshtastic_MeshPacket *p = allocReply(); + if (!p) + return; p->to = dest; p->decoded.want_response = wantReplies; diff --git a/src/modules/esp32/PaxcounterModule.cpp b/src/modules/esp32/PaxcounterModule.cpp index c9eca1c74..db38165c6 100644 --- a/src/modules/esp32/PaxcounterModule.cpp +++ b/src/modules/esp32/PaxcounterModule.cpp @@ -81,6 +81,8 @@ bool PaxcounterModule::sendInfo(NodeNum dest) pl.uptime = millis() / 1000; meshtastic_MeshPacket *p = allocDataProtobuf(pl); + if (!p) + return false; p->to = dest; p->decoded.want_response = false; p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; diff --git a/src/modules/games/GamesModule.cpp b/src/modules/games/GamesModule.cpp index 1d72ba632..606d1d505 100644 --- a/src/modules/games/GamesModule.cpp +++ b/src/modules/games/GamesModule.cpp @@ -105,6 +105,8 @@ void GamesModule::announceHighScore(const char *initials, uint32_t score) if (!initials || initials[0] == '\0') return; meshtastic_MeshPacket *p = allocDataPacket(); + if (!p) + return; p->to = NODENUM_BROADCAST; p->channel = 0; // primary channel p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP; diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index fedafb48e..3d4a20ed7 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -121,6 +121,8 @@ inline void onReceiveProto(char *topic, byte *payload, size_t length) // receives it when we get our own packet back. Then we'll stop our retransmissions. if (isFromUs(e.packet)) { auto pAck = routingModule->allocAckNak(meshtastic_Routing_Error_NONE, getFrom(e.packet), e.packet->id, ch.index); + if (!pAck) + return; pAck->transport_mechanism = meshtastic_MeshPacket_TransportMechanism_TRANSPORT_MQTT; if (router->sendLocal(pAck) == ERRNO_SHOULD_RELEASE) packetPool.release(pAck);