sforkowany z mirror/meshtastic-firmware
add first cut of mesh naive flooding
rodzic
6afeb3e456
commit
ea24394110
2
proto
2
proto
|
@ -1 +1 @@
|
|||
Subproject commit 793d3e65ca66c3a0914e74a285a729429952a042
|
||||
Subproject commit e06645d8db16b9e4f23e74a931b8d5cd07bcbe3c
|
|
@ -214,20 +214,24 @@ void MeshService::handleToRadio(std::string s)
|
|||
switch (r.which_variant) {
|
||||
case ToRadio_packet_tag: {
|
||||
// If our phone is sending a position, see if we can use it to set our RTC
|
||||
handleIncomingPosition(&r.variant.packet); // If it is a position packet, perhaps set our clock
|
||||
MeshPacket &p = r.variant.packet;
|
||||
handleIncomingPosition(&p); // If it is a position packet, perhaps set our clock
|
||||
|
||||
r.variant.packet.rx_time = gps.getValidTime(); // Record the time the packet arrived from the phone (so we update our
|
||||
// nodedb for the local node)
|
||||
if (p.from == 0) // If the phone didn't set a sending node ID, use ours
|
||||
p.from = nodeDB.getNodeNum();
|
||||
|
||||
p.rx_time = gps.getValidTime(); // Record the time the packet arrived from the phone
|
||||
// (so we update our nodedb for the local node)
|
||||
|
||||
// Send the packet into the mesh
|
||||
sendToMesh(packetPool.allocCopy(r.variant.packet));
|
||||
|
||||
sendToMesh(packetPool.allocCopy(p));
|
||||
|
||||
bool loopback = false; // if true send any packet the phone sends back itself (for testing)
|
||||
if (loopback) {
|
||||
const MeshPacket *mp = &r.variant.packet;
|
||||
// no need to copy anymore because handle from radio assumes it should _not_ delete
|
||||
// packetPool.allocCopy(r.variant.packet);
|
||||
handleFromRadio(mp);
|
||||
handleFromRadio(&p);
|
||||
// handleFromRadio will tell the phone a new packet arrived
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <Arduino.h>
|
||||
|
||||
typedef uint8_t NodeNum;
|
||||
typedef uint8_t PacketId; // A packet sequence number
|
||||
|
||||
#define NODENUM_BROADCAST 255
|
||||
#define ERRNO_OK 0
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "error.h"
|
||||
#include "power.h"
|
||||
// #include "rom/rtc.h"
|
||||
#include "FloodingRouter.h"
|
||||
#include "screen.h"
|
||||
#include "sleep.h"
|
||||
#include <Wire.h>
|
||||
|
@ -60,6 +61,9 @@ static meshtastic::PowerStatus powerStatus;
|
|||
bool ssd1306_found;
|
||||
bool axp192_found;
|
||||
|
||||
FloodingRouter realRouter;
|
||||
Router &router = realRouter; // Users of router don't care what sort of subclass implements that API
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Application
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "CustomRF95.h"
|
||||
#include "NodeDB.h"
|
||||
#include "NodeDB.h" // FIXME, this class should not need to touch nodedb
|
||||
#include "assert.h"
|
||||
#include "configuration.h"
|
||||
#include <pb_decode.h>
|
||||
|
@ -97,6 +97,8 @@ void CustomRF95::handleInterrupt()
|
|||
|
||||
mp->from = _rxHeaderFrom;
|
||||
mp->to = _rxHeaderTo;
|
||||
mp->id = _rxHeaderId;
|
||||
|
||||
//_rxHeaderId = _buf[2];
|
||||
//_rxHeaderFlags = _buf[3];
|
||||
|
||||
|
@ -162,9 +164,11 @@ void CustomRF95::startSend(MeshPacket *txp)
|
|||
sendingPacket = txp;
|
||||
|
||||
setHeaderTo(txp->to);
|
||||
setHeaderFrom(nodeDB.getNodeNum()); // We must do this before each send, because we might have just changed our nodenum
|
||||
setHeaderId(txp->id);
|
||||
|
||||
// setHeaderId(0);
|
||||
// if the sender nodenum is zero, that means uninitialized
|
||||
assert(txp->from);
|
||||
setHeaderFrom(txp->from); // We must do this before each send, because we might have just changed our nodenum
|
||||
|
||||
assert(numbytes <= 251); // Make sure we don't overflow the tiny max packet size
|
||||
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
#include "FloodingRouter.h"
|
||||
#include "configuration.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
|
||||
/// We clear our old flood record five minute after we see the last of it
|
||||
#define FLOOD_EXPIRE_TIME (5 * 60 * 1000L)
|
||||
|
||||
FloodingRouter::FloodingRouter()
|
||||
{
|
||||
recentBroadcasts.reserve(MAX_NUM_NODES); // Prealloc the worst case # of records - to prevent heap fragmentation
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
ErrorCode FloodingRouter::send(MeshPacket *p)
|
||||
{
|
||||
// We update our table of recent broadcasts, even for messages we send
|
||||
wasSeenRecently(p);
|
||||
|
||||
return Router::send(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from loop()
|
||||
* Handle any packet that is received by an interface on this node.
|
||||
* Note: some packets may merely being passed through this node and will be forwarded elsewhere.
|
||||
*
|
||||
* Note: this method will free the provided packet
|
||||
*/
|
||||
void FloodingRouter::handleReceived(MeshPacket *p)
|
||||
{
|
||||
if (wasSeenRecently(p)) {
|
||||
DEBUG_MSG("Ignoring incoming floodmsg, because we've already seen it\n");
|
||||
packetPool.release(p);
|
||||
} else {
|
||||
if (p->to == NODENUM_BROADCAST && p->id != 0) {
|
||||
DEBUG_MSG("Rebroadcasting received floodmsg to neighbors\n");
|
||||
// FIXME, wait a random delay
|
||||
|
||||
MeshPacket *tosend = packetPool.allocCopy(*p);
|
||||
// Note: we are careful to resend using the original senders node id
|
||||
Router::send(tosend); // We are careful not to call our hooked version of send()
|
||||
}
|
||||
|
||||
// handle the packet as normal
|
||||
Router::handleReceived(p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update recentBroadcasts and return true if we have already seen this packet
|
||||
*/
|
||||
bool FloodingRouter::wasSeenRecently(const MeshPacket *p)
|
||||
{
|
||||
if (p->to != NODENUM_BROADCAST)
|
||||
return false; // Not a broadcast, so we don't care
|
||||
|
||||
if (p->id == 0)
|
||||
return false; // Not a floodable message ID, so we don't care
|
||||
|
||||
uint32_t now = millis();
|
||||
for (int i = 0; i < recentBroadcasts.size();) {
|
||||
BroadcastRecord &r = recentBroadcasts[i];
|
||||
|
||||
if ((now - r.rxTimeMsec) >= FLOOD_EXPIRE_TIME) {
|
||||
DEBUG_MSG("Deleting old recentBroadcast %d\n", i);
|
||||
recentBroadcasts.erase(recentBroadcasts.begin() + i); // delete old record
|
||||
} else {
|
||||
if (r.id == p->id && r.sender == p->from) {
|
||||
// Update the time on this record to now
|
||||
r.rxTimeMsec = now;
|
||||
return true;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Didn't find an existing record, make one
|
||||
BroadcastRecord r;
|
||||
r.id = p->id;
|
||||
r.sender = p->from;
|
||||
r.rxTimeMsec = now;
|
||||
recentBroadcasts.push_back(r);
|
||||
|
||||
return false;
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
/**
|
||||
* Router todo
|
||||
*
|
||||
* Implement basic interface and use it elsewhere in app
|
||||
* DONE: Implement basic interface and use it elsewhere in app
|
||||
* Add naive flooding mixin (& drop duplicate rx broadcasts), add tools for sending broadcasts with incrementing sequence #s
|
||||
* Add an optional adjacent node only 'send with ack' mixin. If we timeout waiting for the ack, call handleAckTimeout(packet)
|
||||
* Add DSR mixin
|
||||
|
@ -22,8 +22,6 @@
|
|||
|
||||
MemoryPool<MeshPacket> packetPool(MAX_PACKETS);
|
||||
|
||||
Router router;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
#include "mesh.pb.h"
|
||||
#include <RH_RF95.h>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A mesh aware router that supports multiple interfaces.
|
||||
*/
|
||||
|
@ -56,7 +54,7 @@ class Router
|
|||
*/
|
||||
virtual ErrorCode send(MeshPacket *p);
|
||||
|
||||
private:
|
||||
protected:
|
||||
/**
|
||||
* Called from loop()
|
||||
* Handle any packet that is received by an interface on this node.
|
||||
|
@ -64,7 +62,7 @@ class Router
|
|||
*
|
||||
* Note: this method will free the provided packet
|
||||
*/
|
||||
void handleReceived(MeshPacket *p);
|
||||
virtual void handleReceived(MeshPacket *p);
|
||||
};
|
||||
|
||||
extern Router router;
|
||||
extern Router &router;
|
Ładowanie…
Reference in New Issue