mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-16 01:52:04 +00:00
reliable broadcast now works
This commit is contained in:
parent
e75561016b
commit
9dd88281af
@ -247,7 +247,7 @@ void MeshService::sendToMesh(MeshPacket *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Note: We might return !OK if our fifo was full, at that point the only option we have is to drop it
|
// Note: We might return !OK if our fifo was full, at that point the only option we have is to drop it
|
||||||
if (router.send(p) != ERRNO_OK) {
|
if (router.sendLocal(p) != ERRNO_OK) {
|
||||||
DEBUG_MSG("No radio was able to send packet, discarding...\n");
|
DEBUG_MSG("No radio was able to send packet, discarding...\n");
|
||||||
releaseToPool(p);
|
releaseToPool(p);
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,11 @@
|
|||||||
ErrorCode ReliableRouter::send(MeshPacket *p)
|
ErrorCode ReliableRouter::send(MeshPacket *p)
|
||||||
{
|
{
|
||||||
if (p->want_ack) {
|
if (p->want_ack) {
|
||||||
|
// If someone asks for acks on broadcast, we need the hop limit to be at least one, so that first node that receives our
|
||||||
|
// message will rebroadcast
|
||||||
|
if (p->to == NODENUM_BROADCAST && p->hop_limit == 0)
|
||||||
|
p->hop_limit = 1;
|
||||||
|
|
||||||
auto copy = packetPool.allocCopy(*p);
|
auto copy = packetPool.allocCopy(*p);
|
||||||
startRetransmission(copy);
|
startRetransmission(copy);
|
||||||
}
|
}
|
||||||
@ -42,7 +47,7 @@ void ReliableRouter::handleReceived(MeshPacket *p)
|
|||||||
// If this is the first time we saw this, cancel any retransmissions we have queued up and generate an internal ack for
|
// 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.
|
// the original sending process.
|
||||||
if (stopRetransmission(p->from, p->id)) {
|
if (stopRetransmission(p->from, p->id)) {
|
||||||
DEBUG_MSG("Someone is retransmitting for us, generate implicit ack");
|
DEBUG_MSG("Someone is retransmitting for us, generate implicit ack\n");
|
||||||
sendAckNak(true, p->from, p->id);
|
sendAckNak(true, p->from, p->id);
|
||||||
}
|
}
|
||||||
} else if (p->to == ourNode) { // ignore ack/nak/want_ack packets that are not address to us (for now)
|
} else if (p->to == ourNode) { // ignore ack/nak/want_ack packets that are not address to us (for now)
|
||||||
@ -79,10 +84,10 @@ void ReliableRouter::handleReceived(MeshPacket *p)
|
|||||||
*/
|
*/
|
||||||
void ReliableRouter::sendAckNak(bool isAck, NodeNum to, PacketId idFrom)
|
void ReliableRouter::sendAckNak(bool isAck, NodeNum to, PacketId idFrom)
|
||||||
{
|
{
|
||||||
DEBUG_MSG("Sending an ack=%d,to=%d,idFrom=%d\n", isAck, to, idFrom);
|
|
||||||
auto p = allocForSending();
|
auto p = allocForSending();
|
||||||
p->hop_limit = 0; // Assume just immediate neighbors for now
|
p->hop_limit = 0; // Assume just immediate neighbors for now
|
||||||
p->to = to;
|
p->to = to;
|
||||||
|
DEBUG_MSG("Sending an ack=0x%x,to=0x%x,idFrom=%d,id=%d\n", isAck, to, idFrom, p->id);
|
||||||
|
|
||||||
if (isAck) {
|
if (isAck) {
|
||||||
p->decoded.ack.success_id = idFrom;
|
p->decoded.ack.success_id = idFrom;
|
||||||
@ -92,7 +97,7 @@ void ReliableRouter::sendAckNak(bool isAck, NodeNum to, PacketId idFrom)
|
|||||||
p->decoded.which_ack = SubPacket_fail_id_tag;
|
p->decoded.which_ack = SubPacket_fail_id_tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
send(p);
|
sendLocal(p); // we sometimes send directly to the local node
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NUM_RETRANSMISSIONS 3
|
#define NUM_RETRANSMISSIONS 3
|
||||||
|
@ -48,7 +48,7 @@ struct PendingPacket {
|
|||||||
PendingPacket() {}
|
PendingPacket() {}
|
||||||
PendingPacket(MeshPacket *p);
|
PendingPacket(MeshPacket *p);
|
||||||
|
|
||||||
void setNextTx() { nextTxMsec = millis() + random(30 * 1000, 22 * 1000); }
|
void setNextTx() { nextTxMsec = millis() + random(20 * 1000, 22 * 1000); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class GlobalPacketIdHashFunction
|
class GlobalPacketIdHashFunction
|
||||||
|
@ -77,6 +77,16 @@ MeshPacket *Router::allocForSending()
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorCode Router::sendLocal(MeshPacket *p)
|
||||||
|
{
|
||||||
|
if (p->to == nodeDB.getNodeNum()) {
|
||||||
|
DEBUG_MSG("Enqueuing internal message for the receive queue\n");
|
||||||
|
fromRadioQueue.enqueue(p);
|
||||||
|
return ERRNO_OK;
|
||||||
|
} else
|
||||||
|
return send(p);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a packet on a suitable interface. This routine will
|
* Send a packet on a suitable interface. This routine will
|
||||||
* later free() the packet to pool. This routine is not allowed to stall.
|
* later free() the packet to pool. This routine is not allowed to stall.
|
||||||
@ -84,12 +94,8 @@ MeshPacket *Router::allocForSending()
|
|||||||
*/
|
*/
|
||||||
ErrorCode Router::send(MeshPacket *p)
|
ErrorCode Router::send(MeshPacket *p)
|
||||||
{
|
{
|
||||||
// If this packet was destined only to apps on our node, don't send it out into the network
|
assert(p->to != nodeDB.getNodeNum()); // should have already been handled by sendLocal
|
||||||
if (p->to == nodeDB.getNodeNum()) {
|
|
||||||
DEBUG_MSG("Dropping locally processed message\n");
|
|
||||||
packetPool.release(p);
|
|
||||||
return ERRNO_OK;
|
|
||||||
} else {
|
|
||||||
// Never set the want_ack flag on broadcast packets sent over the air.
|
// Never set the want_ack flag on broadcast packets sent over the air.
|
||||||
if (p->to == NODENUM_BROADCAST)
|
if (p->to == NODENUM_BROADCAST)
|
||||||
p->want_ack = false;
|
p->want_ack = false;
|
||||||
@ -123,7 +129,6 @@ ErrorCode Router::send(MeshPacket *p)
|
|||||||
return ERRNO_NO_INTERFACES;
|
return ERRNO_NO_INTERFACES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to
|
* Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to
|
||||||
@ -132,7 +137,6 @@ ErrorCode Router::send(MeshPacket *p)
|
|||||||
void Router::sniffReceived(const MeshPacket *p)
|
void Router::sniffReceived(const MeshPacket *p)
|
||||||
{
|
{
|
||||||
DEBUG_MSG("FIXME-update-db Sniffing packet fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id);
|
DEBUG_MSG("FIXME-update-db Sniffing packet fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Router::perhapsDecode(MeshPacket *p)
|
bool Router::perhapsDecode(MeshPacket *p)
|
||||||
|
@ -47,11 +47,9 @@ class Router
|
|||||||
virtual void loop();
|
virtual void loop();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a packet on a suitable interface. This routine will
|
* Works like send, but if we are sending to the local node, we directly put the message in the receive queue
|
||||||
* later free() the packet to pool. This routine is not allowed to stall.
|
|
||||||
* If the txmit queue is full it might return an error
|
|
||||||
*/
|
*/
|
||||||
virtual ErrorCode send(MeshPacket *p);
|
ErrorCode sendLocal(MeshPacket *p);
|
||||||
|
|
||||||
/// Allocate and return a meshpacket which defaults as send to broadcast from the current node.
|
/// Allocate and return a meshpacket which defaults as send to broadcast from the current node.
|
||||||
MeshPacket *allocForSending();
|
MeshPacket *allocForSending();
|
||||||
@ -61,6 +59,13 @@ class Router
|
|||||||
NodeNum getNodeNum();
|
NodeNum getNodeNum();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/**
|
||||||
|
* Send a packet on a suitable interface. This routine will
|
||||||
|
* later free() the packet to pool. This routine is not allowed to stall.
|
||||||
|
* If the txmit queue is full it might return an error
|
||||||
|
*/
|
||||||
|
virtual ErrorCode send(MeshPacket *p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from loop()
|
* Called from loop()
|
||||||
* Handle any packet that is received by an interface on this node.
|
* Handle any packet that is received by an interface on this node.
|
||||||
|
Loading…
Reference in New Issue
Block a user