sforkowany z mirror/meshtastic-firmware
reliable broadcast now works
rodzic
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
|
||||
if (router.send(p) != ERRNO_OK) {
|
||||
if (router.sendLocal(p) != ERRNO_OK) {
|
||||
DEBUG_MSG("No radio was able to send packet, discarding...\n");
|
||||
releaseToPool(p);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,11 @@
|
|||
ErrorCode ReliableRouter::send(MeshPacket *p)
|
||||
{
|
||||
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);
|
||||
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
|
||||
// the original sending process.
|
||||
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);
|
||||
}
|
||||
} 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)
|
||||
{
|
||||
DEBUG_MSG("Sending an ack=%d,to=%d,idFrom=%d\n", isAck, to, idFrom);
|
||||
auto p = allocForSending();
|
||||
p->hop_limit = 0; // Assume just immediate neighbors for now
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
send(p);
|
||||
sendLocal(p); // we sometimes send directly to the local node
|
||||
}
|
||||
|
||||
#define NUM_RETRANSMISSIONS 3
|
||||
|
|
|
@ -48,7 +48,7 @@ struct PendingPacket {
|
|||
PendingPacket() {}
|
||||
PendingPacket(MeshPacket *p);
|
||||
|
||||
void setNextTx() { nextTxMsec = millis() + random(30 * 1000, 22 * 1000); }
|
||||
void setNextTx() { nextTxMsec = millis() + random(20 * 1000, 22 * 1000); }
|
||||
};
|
||||
|
||||
class GlobalPacketIdHashFunction
|
||||
|
|
|
@ -77,6 +77,16 @@ MeshPacket *Router::allocForSending()
|
|||
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
|
||||
* later free() the packet to pool. This routine is not allowed to stall.
|
||||
|
@ -84,44 +94,39 @@ MeshPacket *Router::allocForSending()
|
|||
*/
|
||||
ErrorCode Router::send(MeshPacket *p)
|
||||
{
|
||||
// If this packet was destined only to apps on our node, don't send it out into the network
|
||||
if (p->to == nodeDB.getNodeNum()) {
|
||||
DEBUG_MSG("Dropping locally processed message\n");
|
||||
packetPool.release(p);
|
||||
return ERRNO_OK;
|
||||
assert(p->to != nodeDB.getNodeNum()); // should have already been handled by sendLocal
|
||||
|
||||
// Never set the want_ack flag on broadcast packets sent over the air.
|
||||
if (p->to == NODENUM_BROADCAST)
|
||||
p->want_ack = false;
|
||||
|
||||
// If the packet hasn't yet been encrypted, do so now (it might already be encrypted if we are just forwarding it)
|
||||
|
||||
assert(p->which_payload == MeshPacket_encrypted_tag ||
|
||||
p->which_payload == MeshPacket_decoded_tag); // I _think_ all packets should have a payload by now
|
||||
|
||||
// First convert from protobufs to raw bytes
|
||||
if (p->which_payload == MeshPacket_decoded_tag) {
|
||||
static uint8_t bytes[MAX_RHPACKETLEN]; // we have to use a scratch buffer because a union
|
||||
|
||||
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), SubPacket_fields, &p->decoded);
|
||||
|
||||
assert(numbytes <= MAX_RHPACKETLEN);
|
||||
crypto->encrypt(p->from, p->id, numbytes, bytes);
|
||||
|
||||
// Copy back into the packet and set the variant type
|
||||
memcpy(p->encrypted.bytes, bytes, numbytes);
|
||||
p->encrypted.size = numbytes;
|
||||
p->which_payload = MeshPacket_encrypted_tag;
|
||||
}
|
||||
|
||||
if (iface) {
|
||||
// DEBUG_MSG("Sending packet via interface fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id);
|
||||
return iface->send(p);
|
||||
} else {
|
||||
// Never set the want_ack flag on broadcast packets sent over the air.
|
||||
if (p->to == NODENUM_BROADCAST)
|
||||
p->want_ack = false;
|
||||
|
||||
// If the packet hasn't yet been encrypted, do so now (it might already be encrypted if we are just forwarding it)
|
||||
|
||||
assert(p->which_payload == MeshPacket_encrypted_tag ||
|
||||
p->which_payload == MeshPacket_decoded_tag); // I _think_ all packets should have a payload by now
|
||||
|
||||
// First convert from protobufs to raw bytes
|
||||
if (p->which_payload == MeshPacket_decoded_tag) {
|
||||
static uint8_t bytes[MAX_RHPACKETLEN]; // we have to use a scratch buffer because a union
|
||||
|
||||
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), SubPacket_fields, &p->decoded);
|
||||
|
||||
assert(numbytes <= MAX_RHPACKETLEN);
|
||||
crypto->encrypt(p->from, p->id, numbytes, bytes);
|
||||
|
||||
// Copy back into the packet and set the variant type
|
||||
memcpy(p->encrypted.bytes, bytes, numbytes);
|
||||
p->encrypted.size = numbytes;
|
||||
p->which_payload = MeshPacket_encrypted_tag;
|
||||
}
|
||||
|
||||
if (iface) {
|
||||
// DEBUG_MSG("Sending packet via interface fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id);
|
||||
return iface->send(p);
|
||||
} else {
|
||||
DEBUG_MSG("Dropping packet - no interfaces - fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id);
|
||||
packetPool.release(p);
|
||||
return ERRNO_NO_INTERFACES;
|
||||
}
|
||||
DEBUG_MSG("Dropping packet - no interfaces - fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id);
|
||||
packetPool.release(p);
|
||||
return ERRNO_NO_INTERFACES;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,7 +137,6 @@ ErrorCode Router::send(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);
|
||||
|
||||
}
|
||||
|
||||
bool Router::perhapsDecode(MeshPacket *p)
|
||||
|
|
|
@ -47,11 +47,9 @@ class Router
|
|||
virtual void loop();
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Works like send, but if we are sending to the local node, we directly put the message in the receive queue
|
||||
*/
|
||||
virtual ErrorCode send(MeshPacket *p);
|
||||
ErrorCode sendLocal(MeshPacket *p);
|
||||
|
||||
/// Allocate and return a meshpacket which defaults as send to broadcast from the current node.
|
||||
MeshPacket *allocForSending();
|
||||
|
@ -61,6 +59,13 @@ class Router
|
|||
NodeNum getNodeNum();
|
||||
|
||||
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()
|
||||
* Handle any packet that is received by an interface on this node.
|
||||
|
|
Ładowanie…
Reference in New Issue