diff --git a/src/mesh/FloodingRouter.cpp b/src/mesh/FloodingRouter.cpp index 925735903..92df575b1 100644 --- a/src/mesh/FloodingRouter.cpp +++ b/src/mesh/FloodingRouter.cpp @@ -34,7 +34,8 @@ void FloodingRouter::sniffReceived(const MeshPacket *p, const Routing *c) // do not flood direct message that is ACKed DEBUG_MSG("Receiving an ACK not for me, but don't need to rebroadcast this direct message anymore.\n"); Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM - } else if ((p->to != getNodeNum()) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) { + } + if ((p->to != getNodeNum()) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) { if (p->id != 0) { if (config.device.role != Config_DeviceConfig_Role_CLIENT_MUTE) { MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it diff --git a/src/mesh/MeshModule.cpp b/src/mesh/MeshModule.cpp index 923b4f471..02289f863 100644 --- a/src/mesh/MeshModule.cpp +++ b/src/mesh/MeshModule.cpp @@ -48,7 +48,7 @@ MeshPacket *MeshModule::allocAckNak(Routing_Error err, NodeNum to, PacketId idFr p->priority = MeshPacket_Priority_ACK; - p->hop_limit = 0; // Assume just immediate neighbors for now + p->hop_limit = config.lora.hop_limit; // Assume just immediate neighbors for now p->to = to; p->decoded.request_id = idFrom; p->channel = chIndex; diff --git a/src/mesh/PacketHistory.cpp b/src/mesh/PacketHistory.cpp index c8008689d..9d2c7a8ed 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 PacketHistory::wasSeenRecently(const MeshPacket *p, bool withUpdate) //, bool checkAck { if (p->id == 0) { DEBUG_MSG("Ignoring message with zero id\n"); @@ -24,6 +24,12 @@ bool PacketHistory::wasSeenRecently(const MeshPacket *p, bool withUpdate) 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 @@ -52,7 +58,7 @@ bool PacketHistory::wasSeenRecently(const MeshPacket *p, bool withUpdate) clearExpiredRecentPackets(); } - return seenRecently; + return seenRecently; //checkAck ? seenAck : } /** diff --git a/src/mesh/PacketHistory.h b/src/mesh/PacketHistory.h index d44a3d369..abdc78c4f 100644 --- a/src/mesh/PacketHistory.h +++ b/src/mesh/PacketHistory.h @@ -13,6 +13,7 @@ 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 222e5d14b..9ee66da0d 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 2*packetAirtime + (pow(2, CWsize) + pow(2, int((CWmax+CWmin)/2))) * slotTimeMsec + PROCESSING_TIME_MSEC; + return 1000*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 7933a7920..a60c37ebc 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); + startRetransmission(copy); // TODO: also on not want_ack? } return FloodingRouter::send(p); @@ -37,27 +37,29 @@ bool ReliableRouter::shouldFilterReceived(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. - // FIXME - we might want to turn off this "optimization", it does save lots of airtime but it assumes that once we've - // heard one one adjacent node hear our packet that a) probably other adjacent nodes heard it and b) we can trust those - // nodes to reach our destination. Both of which might be incorrect. + // 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. auto key = GlobalPacketId(getFrom(p), p->id); auto old = findPendingPacket(key); if (old) { - 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); - + // 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"); stopRetransmission(key); - } else { - DEBUG_MSG("didn't find pending packet\n"); } } + + //bool isAck = ((c && c->error_reason == Routing_Error_NONE)); // consider only ROUTING_APP message without error as ACK /* send acks for repeated packets that want acks and are destined for us - * this way if an ACK is dropped and a packet is resent we'll ACK the resent packet - * make sure wasSeenRecently _doesn't_ update - * finding the channel requires decoding the packet. */ + * this way if an ACK is dropped and a packet is resent we'll ACK the resent packet + * make sure wasSeenRecently _doesn't_ update + * finding the channel requires decoding the packet. */ if (p->want_ack && (p->to == getNodeNum()) && wasSeenRecently(p, false) && !MeshModule::currentReply) { if (perhapsDecode(p)) { sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel); diff --git a/src/modules/NodeInfoModule.cpp b/src/modules/NodeInfoModule.cpp index 1ce1acf33..b5d6c30da 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() diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index 013f2ee44..df9ee6816 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)