diff --git a/src/mesh/PacketHistory.cpp b/src/mesh/PacketHistory.cpp index 9d2c7a8ed..a1e0f6bd5 100644 --- a/src/mesh/PacketHistory.cpp +++ b/src/mesh/PacketHistory.cpp @@ -11,7 +11,7 @@ PacketHistory::PacketHistory() /** * Update recentBroadcasts and return true if we have already seen this packet */ -bool PacketHistory::wasSeenRecently(const MeshPacket *p, bool withUpdate) //, bool checkAck +bool PacketHistory::wasSeenRecently(const MeshPacket *p, bool withUpdate) { if (p->id == 0) { DEBUG_MSG("Ignoring message with zero id\n"); @@ -24,12 +24,6 @@ bool PacketHistory::wasSeenRecently(const MeshPacket *p, bool withUpdate) //, b r.id = p->id; r.sender = getFrom(p); r.rxTimeMsec = now; - // if (checkAck) - // if (p->which_payload_variant == MeshPacket_decoded_tag && p->decoded.portnum == PortNum_ROUTING_APP) { - // perhapsDecode(p); - // bool seenAck = (p-> == ) - // } - // r.seenAck = p-> auto found = recentPackets.find(r); bool seenRecently = (found != recentPackets.end()); // found not equal to .end() means packet was seen recently @@ -58,7 +52,7 @@ bool PacketHistory::wasSeenRecently(const MeshPacket *p, bool withUpdate) //, b clearExpiredRecentPackets(); } - return seenRecently; //checkAck ? seenAck : + return seenRecently; } /** @@ -78,4 +72,4 @@ void PacketHistory::clearExpiredRecentPackets() { } DEBUG_MSG("recentPackets size=%ld (after clearing expired packets)\n", recentPackets.size()); -} \ No newline at end of file +} diff --git a/src/mesh/PacketHistory.h b/src/mesh/PacketHistory.h index abdc78c4f..d44a3d369 100644 --- a/src/mesh/PacketHistory.h +++ b/src/mesh/PacketHistory.h @@ -13,7 +13,6 @@ struct PacketRecord { NodeNum sender; PacketId id; uint32_t rxTimeMsec; // Unix time in msecs - the time we received it - //bool seenAck; bool operator==(const PacketRecord &p) const { return sender == p.sender && id == p.id; } }; diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 9ee66da0d..222e5d14b 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -182,7 +182,7 @@ uint32_t RadioInterface::getRetransmissionMsec(const MeshPacket *p) float channelUtil = airTime->channelUtilizationPercent(); uint8_t CWsize = map(channelUtil, 0, 100, CWmin, CWmax); // Assuming we pick max. of CWsize and there will be a receiver with SNR at half the range - return 1000*packetAirtime + (pow(2, CWsize) + pow(2, int((CWmax+CWmin)/2))) * slotTimeMsec + PROCESSING_TIME_MSEC; + return 2*packetAirtime + (pow(2, CWsize) + pow(2, int((CWmax+CWmin)/2))) * slotTimeMsec + PROCESSING_TIME_MSEC; } /** The delay to use when we want to send something */ diff --git a/src/mesh/ReliableRouter.cpp b/src/mesh/ReliableRouter.cpp index ba886ed71..22f3692b9 100644 --- a/src/mesh/ReliableRouter.cpp +++ b/src/mesh/ReliableRouter.cpp @@ -21,7 +21,7 @@ ErrorCode ReliableRouter::send(MeshPacket *p) } auto copy = packetPool.allocCopy(*p); - startRetransmission(copy); // TODO: also on not want_ack? + startRetransmission(copy); } return FloodingRouter::send(p); @@ -37,26 +37,26 @@ bool ReliableRouter::shouldFilterReceived(const MeshPacket *p) // If this is the first time we saw this, cancel any retransmissions we have queued up and generate an internal ack for // the original sending process. - // This "optimization", does save lots of airtime, but can be turned off for direct messages to get - // a confirmation from the specific node it was sent to. + // This "optimization", does save lots of airtime. For DMs, you also get a real ACK back + // from the intended recipient. auto key = GlobalPacketId(getFrom(p), p->id); auto old = findPendingPacket(key); if (old) { - // Only if want_ack was not set, we mark the packet as ACKed already on an implicit ACK - if (!p->want_ack) { - DEBUG_MSG("generating implicit ack\n"); - sendAckNak(Routing_Error_NONE, getFrom(p), p->id, old->packet->channel); - } - // At this point we assume it will arrive. - // We don't now how long we have to wait for the real ACK so stop retransmissions. - DEBUG_MSG("Stopping retransmissions\n"); + DEBUG_MSG("generating implicit ack\n"); + // NOTE: we do NOT check p->wantAck here because p is the INCOMING rebroadcast and that packet is not expected to be + // marked as wantAck + sendAckNak(Routing_Error_NONE, getFrom(p), p->id, old->packet->channel); + stopRetransmission(key); + } else { + DEBUG_MSG("didn't find pending packet\n"); } } - /* Resend implicit ACKs for repeated packets (assuming original packet was sent with HOP_RELIABLE) - * this way if an implicit ACK is dropped and a packet is resent we'll rebroadcast again - * Not used for real ACKs, as you might receive a packet multiple times due to flooding. */ + /* Resend implicit ACKs for repeated packets (assuming the original packet was sent with HOP_RELIABLE) + * this way if an implicit ACK is dropped and a packet is resent we'll rebroadcast again. + * Resending real ACKs is omitted, as you might receive a packet multiple times due to flooding and + * flooding this ACK back to the original sender already adds redundancy. */ if (wasSeenRecently(p, false) && p->hop_limit == HOP_RELIABLE && !MeshModule::currentReply && p->to != nodeDB.getNodeNum()) { // retransmission on broadcast has hop_limit still equal to HOP_RELIABLE DEBUG_MSG("Resending implicit ack for a repeated floodmsg\n"); diff --git a/src/modules/NodeInfoModule.cpp b/src/modules/NodeInfoModule.cpp index b5d6c30da..fc1d143ee 100644 --- a/src/modules/NodeInfoModule.cpp +++ b/src/modules/NodeInfoModule.cpp @@ -54,7 +54,7 @@ NodeInfoModule::NodeInfoModule() : ProtobufModule("nodeinfo", PortNum_NODEINFO_APP, &User_msg), concurrency::OSThread("NodeInfoModule") { isPromiscuous = true; // We always want to update our nodedb, even if we are sniffing on others - //setIntervalFromNow(30 * 1000); // Send our initial owner announcement 30 seconds after we start (to give network time to setup) + setIntervalFromNow(30 * 1000); // Send our initial owner announcement 30 seconds after we start (to give network time to setup) } int32_t NodeInfoModule::runOnce() @@ -69,4 +69,4 @@ int32_t NodeInfoModule::runOnce() sendOurNodeInfo(NODENUM_BROADCAST, requestReplies); // Send our info (don't request replies) return default_broadcast_interval_secs * 1000; -} \ No newline at end of file +} diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index df9ee6816..013f2ee44 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -13,7 +13,7 @@ PositionModule::PositionModule() : ProtobufModule("position", PortNum_POSITION_APP, &Position_msg), concurrency::OSThread("PositionModule") { isPromiscuous = true; // We always want to update our nodedb, even if we are sniffing on others - //setIntervalFromNow(60 * 1000); // Send our initial position 60 seconds after we start (to give GPS time to setup) + setIntervalFromNow(60 * 1000); // Send our initial position 60 seconds after we start (to give GPS time to setup) } bool PositionModule::handleReceivedProtobuf(const MeshPacket &mp, Position *pptr)