diff --git a/src/mesh/ReliableRouter.cpp b/src/mesh/ReliableRouter.cpp index 6d098b669..cca838ff0 100644 --- a/src/mesh/ReliableRouter.cpp +++ b/src/mesh/ReliableRouter.cpp @@ -97,27 +97,34 @@ bool ReliableRouter::shouldFilterReceived(const meshtastic_MeshPacket *p) void ReliableRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c) { if (isToUs(p)) { // ignore ack/nak/want_ack packets that are not address to us (we only handle 0 hop reliability) - if (p->want_ack) { - if (MeshModule::currentReply) { - LOG_DEBUG("Another module replied to this message, no need for 2nd ack"); - } else if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) { - // A response may be set to want_ack for retransmissions, but we don't need to ACK a response if it received an - // implicit ACK already. If we received it directly, only ACK with a hop limit of 0 - if (!p->decoded.request_id) - sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel, + if (!MeshModule::currentReply) { + if (p->want_ack) { + if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) { + /* A response may be set to want_ack for retransmissions, but we don't need to ACK a response if it received + an implicit ACK already. If we received it directly or via NextHopRouter, only ACK with a hop limit of 0 to + make sure the other side stops retransmitting. */ + if (!p->decoded.request_id && !p->decoded.reply_id) { + sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel, + routingModule->getHopLimitForResponse(p->hop_start, p->hop_limit)); + } else if ((p->hop_start > 0 && p->hop_start == p->hop_limit) || p->next_hop != NO_NEXT_HOP_PREFERENCE) { + sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel, 0); + } + } else if (p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag && p->channel == 0 && + (nodeDB->getMeshNode(p->from) == nullptr || nodeDB->getMeshNode(p->from)->user.public_key.size == 0)) { + LOG_INFO("PKI packet from unknown node, send PKI_UNKNOWN_PUBKEY"); + sendAckNak(meshtastic_Routing_Error_PKI_UNKNOWN_PUBKEY, getFrom(p), p->id, channels.getPrimaryIndex(), routingModule->getHopLimitForResponse(p->hop_start, p->hop_limit)); - else if (p->hop_start > 0 && p->hop_start == p->hop_limit) - sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel, 0); - } else if (p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag && p->channel == 0 && - (nodeDB->getMeshNode(p->from) == nullptr || nodeDB->getMeshNode(p->from)->user.public_key.size == 0)) { - LOG_INFO("PKI packet from unknown node, send PKI_UNKNOWN_PUBKEY"); - sendAckNak(meshtastic_Routing_Error_PKI_UNKNOWN_PUBKEY, getFrom(p), p->id, channels.getPrimaryIndex(), - routingModule->getHopLimitForResponse(p->hop_start, p->hop_limit)); - } else { - // Send a 'NO_CHANNEL' error on the primary channel if want_ack packet destined for us cannot be decoded - sendAckNak(meshtastic_Routing_Error_NO_CHANNEL, getFrom(p), p->id, channels.getPrimaryIndex(), - routingModule->getHopLimitForResponse(p->hop_start, p->hop_limit)); + } else { + // Send a 'NO_CHANNEL' error on the primary channel if want_ack packet destined for us cannot be decoded + sendAckNak(meshtastic_Routing_Error_NO_CHANNEL, getFrom(p), p->id, channels.getPrimaryIndex(), + routingModule->getHopLimitForResponse(p->hop_start, p->hop_limit)); + } + } else if (p->next_hop == nodeDB->getLastByteOfNodeNum(getNodeNum()) && p->hop_limit > 0) { + // No wantAck, but we need to ACK with hop limit of 0 if we were the next hop to stop their retransmissions + sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel, 0); } + } else { + LOG_DEBUG("Another module replied to this message, no need for 2nd ack"); } if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag && c && c->error_reason == meshtastic_Routing_Error_PKI_UNKNOWN_PUBKEY) {