partial for #681: Never let stale nodeinfos/positions stay in xmit queue

This commit is contained in:
Kevin Hester 2021-02-11 17:39:53 +08:00
parent fdfe62edf0
commit 917090856f
11 changed files with 53 additions and 2 deletions

View File

@ -169,6 +169,11 @@ void MeshService::handleToRadio(MeshPacket &p)
} }
} }
/** Attempt to cancel a previously sent packet from this _local_ node. Returns true if a packet was found we could cancel */
bool MeshService::cancelSending(PacketId id) {
return router->cancelSending(nodeDB.getNodeNum(), id);
}
void MeshService::sendToMesh(MeshPacket *p) void MeshService::sendToMesh(MeshPacket *p)
{ {
nodeDB.updateFrom(*p); // update our local DB for this packet (because phone might have sent position packets etc...) nodeDB.updateFrom(*p); // update our local DB for this packet (because phone might have sent position packets etc...)

View File

@ -79,6 +79,9 @@ class MeshService
/// cache /// cache
void sendToMesh(MeshPacket *p); void sendToMesh(MeshPacket *p);
/** Attempt to cancel a previously sent packet from this _local_ node. Returns true if a packet was found we could cancel */
bool cancelSending(PacketId id);
/// Pull the latest power and time info into my nodeinfo /// Pull the latest power and time info into my nodeinfo
NodeInfo *refreshMyNodeInfo(); NodeInfo *refreshMyNodeInfo();

View File

@ -105,6 +105,9 @@ class RadioInterface
*/ */
virtual ErrorCode send(MeshPacket *p) = 0; virtual ErrorCode send(MeshPacket *p) = 0;
/** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */
virtual bool cancelSending(NodeNum from, PacketId id) { return false; }
// methods from radiohead // methods from radiohead
/// Initialise the Driver transport hardware and software. /// Initialise the Driver transport hardware and software.

View File

@ -132,6 +132,13 @@ bool RadioLibInterface::canSleep()
return res; return res;
} }
/** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */
bool RadioLibInterface::cancelSending(NodeNum from, PacketId id) {
assert(0);
return false;
}
/** radio helper thread callback. /** radio helper thread callback.
We never immediately transmit after any operation (either rx or tx). Instead we should start receiving and We never immediately transmit after any operation (either rx or tx). Instead we should start receiving and

View File

@ -136,6 +136,9 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
*/ */
virtual bool isActivelyReceiving() = 0; virtual bool isActivelyReceiving() = 0;
/** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */
virtual bool cancelSending(NodeNum from, PacketId id);
private: private:
/** if we have something waiting to send, start a short random timer so we can come check for collision before actually doing /** if we have something waiting to send, start a short random timer so we can come check for collision before actually doing
* the transmit * the transmit

View File

@ -124,6 +124,8 @@ void Router::sendAckNak(ErrorReason err, NodeNum to, PacketId idFrom)
sendLocal(p); // we sometimes send directly to the local node sendLocal(p); // we sometimes send directly to the local node
} }
ErrorCode Router::sendLocal(MeshPacket *p) ErrorCode Router::sendLocal(MeshPacket *p)
{ {
// No need to deliver externally if the destination is the local node // No need to deliver externally if the destination is the local node
@ -199,6 +201,13 @@ ErrorCode Router::send(MeshPacket *p)
} */ } */
} }
/** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */
bool Router::cancelSending(NodeNum from, PacketId id) {
return iface ? iface->cancelSending(from, id) : false;
}
/** /**
* 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
* update routing tables etc... based on what we overhear (even for messages not destined to our node) * update routing tables etc... based on what we overhear (even for messages not destined to our node)

View File

@ -55,7 +55,12 @@ class Router : protected concurrency::OSThread
*/ */
ErrorCode sendLocal(MeshPacket *p); ErrorCode sendLocal(MeshPacket *p);
/// Allocate and return a meshpacket which defaults as send to broadcast from the current node. /** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */
bool cancelSending(NodeNum from, PacketId id);
/** Allocate and return a meshpacket which defaults as send to broadcast from the current node.
* The returned packet is guaranteed to have a unique packet ID already assigned
*/
MeshPacket *allocForSending(); MeshPacket *allocForSending();
/** /**

View File

@ -28,10 +28,15 @@ bool NodeInfoPlugin::handleReceivedProtobuf(const MeshPacket &mp, const User &p)
void NodeInfoPlugin::sendOurNodeInfo(NodeNum dest, bool wantReplies) void NodeInfoPlugin::sendOurNodeInfo(NodeNum dest, bool wantReplies)
{ {
// cancel any not yet sent (now stale) position packets
if(prevPacketId) // if we wrap around to zero, we'll simply fail to cancel in that rare case (no big deal)
service.cancelSending(prevPacketId);
MeshPacket *p = allocReply(); MeshPacket *p = allocReply();
p->to = dest; p->to = dest;
p->decoded.want_response = wantReplies; p->decoded.want_response = wantReplies;
prevPacketId = p->id;
service.sendToMesh(p); service.sendToMesh(p);
} }

View File

@ -6,6 +6,9 @@
*/ */
class NodeInfoPlugin : public ProtobufPlugin<User> class NodeInfoPlugin : public ProtobufPlugin<User>
{ {
/// The id of the last packet we sent, to allow us to cancel it if we make something fresher
PacketId prevPacketId = 0;
public: public:
/** Constructor /** Constructor
* name is for debugging output * name is for debugging output

View File

@ -37,9 +37,14 @@ MeshPacket *PositionPlugin::allocReply()
void PositionPlugin::sendOurPosition(NodeNum dest, bool wantReplies) void PositionPlugin::sendOurPosition(NodeNum dest, bool wantReplies)
{ {
// cancel any not yet sent (now stale) position packets
if(prevPacketId) // if we wrap around to zero, we'll simply fail to cancel in that rare case (no big deal)
service.cancelSending(prevPacketId);
MeshPacket *p = allocReply(); MeshPacket *p = allocReply();
p->to = dest; p->to = dest;
p->decoded.want_response = wantReplies; p->decoded.want_response = wantReplies;
prevPacketId = p->id;
service.sendToMesh(p); service.sendToMesh(p);
} }

View File

@ -6,6 +6,9 @@
*/ */
class PositionPlugin : public ProtobufPlugin<Position> class PositionPlugin : public ProtobufPlugin<Position>
{ {
/// The id of the last packet we sent, to allow us to cancel it if we make something fresher
PacketId prevPacketId = 0;
public: public:
/** Constructor /** Constructor
* name is for debugging output * name is for debugging output