2020-04-17 16:48:54 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "MemoryPool.h"
|
|
|
|
#include "MeshTypes.h"
|
|
|
|
#include "Observer.h"
|
|
|
|
#include "PointerQueue.h"
|
|
|
|
#include "RadioInterface.h"
|
2020-10-09 06:16:51 +00:00
|
|
|
#include "concurrency/OSThread.h"
|
2020-04-17 16:48:54 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A mesh aware router that supports multiple interfaces.
|
|
|
|
*/
|
2020-10-09 06:16:51 +00:00
|
|
|
class Router : protected concurrency::OSThread
|
2020-04-17 16:48:54 +00:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
/// Packets which have just arrived from the radio, ready to be processed by this service and possibly
|
|
|
|
/// forwarded to the phone.
|
|
|
|
PointerQueue<MeshPacket> fromRadioQueue;
|
|
|
|
|
2020-11-12 09:49:04 +00:00
|
|
|
protected:
|
|
|
|
RadioInterface *iface = NULL;
|
|
|
|
|
2020-04-17 16:48:54 +00:00
|
|
|
public:
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
Router();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Currently we only allow one interface, that may change in the future
|
|
|
|
*/
|
|
|
|
void addInterface(RadioInterface *_iface)
|
|
|
|
{
|
|
|
|
iface = _iface;
|
|
|
|
iface->setReceiver(&fromRadioQueue);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* do idle processing
|
|
|
|
* Mostly looking in our incoming rxPacket queue and calling handleReceived.
|
|
|
|
*/
|
2020-10-10 01:57:57 +00:00
|
|
|
virtual int32_t runOnce();
|
2020-04-17 16:48:54 +00:00
|
|
|
|
|
|
|
/**
|
2021-02-07 02:26:11 +00:00
|
|
|
* Works like send, but if we are sending to the local node, we directly put the message in the receive queue.
|
|
|
|
* This is the primary method used for sending packets, because it handles both the remote and local cases.
|
2020-05-25 15:19:14 +00:00
|
|
|
*
|
|
|
|
* NOTE: This method will free the provided packet (even if we return an error code)
|
2020-04-17 16:48:54 +00:00
|
|
|
*/
|
2020-05-21 23:34:16 +00:00
|
|
|
ErrorCode sendLocal(MeshPacket *p);
|
2020-04-17 16:48:54 +00:00
|
|
|
|
2021-02-11 09:39:53 +00:00
|
|
|
/** 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
|
|
|
|
*/
|
2020-05-19 18:56:17 +00:00
|
|
|
MeshPacket *allocForSending();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return our local nodenum */
|
|
|
|
NodeNum getNodeNum();
|
|
|
|
|
2020-04-17 18:52:20 +00:00
|
|
|
protected:
|
2021-02-17 05:06:23 +00:00
|
|
|
friend class RoutingPlugin;
|
|
|
|
|
2020-05-21 23:34:16 +00:00
|
|
|
/**
|
|
|
|
* 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
|
2020-05-25 15:19:14 +00:00
|
|
|
*
|
|
|
|
* NOTE: This method will free the provided packet (even if we return an error code)
|
2020-05-21 23:34:16 +00:00
|
|
|
*/
|
|
|
|
virtual ErrorCode send(MeshPacket *p);
|
|
|
|
|
2020-04-17 16:48:54 +00:00
|
|
|
/**
|
2020-05-23 16:24:22 +00:00
|
|
|
* Should this incoming filter be dropped?
|
2021-02-17 05:06:23 +00:00
|
|
|
*
|
|
|
|
* FIXME, move this into the new RoutingPlugin and do the filtering there using the regular plugin logic
|
2020-04-17 16:48:54 +00:00
|
|
|
*
|
2020-05-23 16:24:22 +00:00
|
|
|
* Called immedately on receiption, before any further processing.
|
|
|
|
* @return true to abandon the packet
|
2020-04-17 16:48:54 +00:00
|
|
|
*/
|
2020-05-23 16:24:22 +00:00
|
|
|
virtual bool shouldFilterReceived(const MeshPacket *p) { return false; }
|
2020-05-19 00:57:58 +00:00
|
|
|
|
|
|
|
/**
|
2020-05-19 18:56:17 +00:00
|
|
|
* Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to
|
2020-05-19 00:57:58 +00:00
|
|
|
* update routing tables etc... based on what we overhear (even for messages not destined to our node)
|
|
|
|
*/
|
2021-02-21 04:59:47 +00:00
|
|
|
virtual void sniffReceived(const MeshPacket *p, const Routing *c);
|
2020-05-19 18:56:17 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove any encryption and decode the protobufs inside this packet (if necessary).
|
|
|
|
*
|
|
|
|
* @return true for success, false for corrupt packet.
|
|
|
|
*/
|
|
|
|
bool perhapsDecode(MeshPacket *p);
|
2020-05-23 16:24:22 +00:00
|
|
|
|
2021-02-07 02:26:11 +00:00
|
|
|
/**
|
|
|
|
* Send an ack or a nak packet back towards whoever sent idFrom
|
|
|
|
*/
|
2021-02-17 05:06:23 +00:00
|
|
|
void sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom);
|
2021-02-07 02:26:11 +00:00
|
|
|
|
2020-05-23 16:24:22 +00:00
|
|
|
private:
|
|
|
|
/**
|
|
|
|
* 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 packet will never be called for messages sent/generated by this node.
|
|
|
|
* Note: this method will free the provided packet.
|
|
|
|
*/
|
|
|
|
void perhapsHandleReceived(MeshPacket *p);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called from perhapsHandleReceived() - allows subclass message delivery behavior.
|
|
|
|
* 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 packet will never be called for messages sent/generated by this node.
|
|
|
|
* Note: this method will free the provided packet.
|
|
|
|
*/
|
|
|
|
void handleReceived(MeshPacket *p);
|
2021-02-22 04:57:26 +00:00
|
|
|
|
|
|
|
/** Frees the provided packet, and generates a NAK indicating the speicifed error while sending */
|
|
|
|
void abortSendAndNak(Routing_Error err, MeshPacket *p);
|
2020-04-17 16:48:54 +00:00
|
|
|
};
|
|
|
|
|
2020-10-10 01:57:57 +00:00
|
|
|
extern Router *router;
|
2020-05-19 18:56:17 +00:00
|
|
|
|
|
|
|
/// Generate a unique packet id
|
|
|
|
// FIXME, move this someplace better
|
|
|
|
PacketId generatePacketId();
|