fix: gate module replies by request port (#11094)
This commit is contained in:
+15
-4
@@ -18,7 +18,7 @@ uint8_t MeshModule::numPeriodicModules = 0;
|
||||
*/
|
||||
meshtastic_MeshPacket *MeshModule::currentReply;
|
||||
|
||||
MeshModule::MeshModule(const char *_name) : name(_name)
|
||||
MeshModule::MeshModule(const char *_name, meshtastic_PortNum _ourPortNum) : name(_name), ourPortNum(_ourPortNum)
|
||||
{
|
||||
// Can't trust static initializer order, so we check each time
|
||||
if (!modules)
|
||||
@@ -27,6 +27,12 @@ MeshModule::MeshModule(const char *_name) : name(_name)
|
||||
modules->push_back(this);
|
||||
}
|
||||
|
||||
bool MeshModule::replyPortMatches(meshtastic_PortNum modulePort, const meshtastic_MeshPacket &mp)
|
||||
{
|
||||
return modulePort != meshtastic_PortNum_UNKNOWN_APP && mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
|
||||
mp.decoded.portnum == modulePort;
|
||||
}
|
||||
|
||||
void MeshModule::setup() {}
|
||||
|
||||
MeshModule::~MeshModule()
|
||||
@@ -107,6 +113,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
|
||||
auto &pi = **i;
|
||||
|
||||
pi.currentRequest = ∓
|
||||
pi.ignoreRequest = false;
|
||||
|
||||
/// We only call modules that are interested in the packet (and the message is destined to us or we are promiscious)
|
||||
bool wantsPacket = (isDecoded || pi.encryptedOk) && (pi.isPromiscuous || toUs) && pi.wantPacket(&mp);
|
||||
@@ -157,9 +164,13 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
|
||||
// better solution (FIXME) would be to let phones have their own distinct addresses and we 'route' to them like
|
||||
// any other node.
|
||||
if (isDecoded && mp.decoded.want_response && toUs && (!isFromUs(&mp) || isToUs(&mp)) && !currentReply) {
|
||||
pi.sendResponse(mp);
|
||||
if (replyPortMatches(pi.ourPortNum, mp)) {
|
||||
pi.sendResponse(mp);
|
||||
LOG_INFO("Asked module '%s' to send a response", pi.name);
|
||||
} else {
|
||||
LOG_DEBUG("Module '%s' cannot respond on portnum=%d", pi.name, mp.decoded.portnum);
|
||||
}
|
||||
ignoreRequest = ignoreRequest || pi.ignoreRequest; // If at least one module asks it, we may ignore a request
|
||||
LOG_INFO("Asked module '%s' to send a response", pi.name);
|
||||
} else {
|
||||
LOG_DEBUG("Module '%s' considered", pi.name);
|
||||
}
|
||||
@@ -313,4 +324,4 @@ bool MeshModule::isRequestingFocus()
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -68,10 +68,12 @@ class MeshModule
|
||||
/** Constructor
|
||||
* name is for debugging output
|
||||
*/
|
||||
MeshModule(const char *_name);
|
||||
MeshModule(const char *_name, meshtastic_PortNum _ourPortNum = meshtastic_PortNum_UNKNOWN_APP);
|
||||
|
||||
virtual ~MeshModule();
|
||||
|
||||
static bool replyPortMatches(meshtastic_PortNum modulePort, const meshtastic_MeshPacket &mp);
|
||||
|
||||
/** For use only by MeshService
|
||||
*/
|
||||
static void callModules(meshtastic_MeshPacket &mp, RxSource src = RX_SRC_RADIO);
|
||||
@@ -88,6 +90,7 @@ class MeshModule
|
||||
#endif
|
||||
protected:
|
||||
const char *name;
|
||||
meshtastic_PortNum ourPortNum;
|
||||
|
||||
/** Most modules only care about packets that are destined for their node (i.e. broadcasts or has their node as the specific
|
||||
recipient) But some plugs might want to 'sniff' packets that are merely being routed (passing through the current node). Those
|
||||
@@ -103,7 +106,7 @@ class MeshModule
|
||||
* flag */
|
||||
bool encryptedOk = false;
|
||||
|
||||
/* We allow modules to ignore a request without sending an error if they have a specific reason for it. */
|
||||
/* Per-packet flag cleared by callModules(); modules can suppress an error response for a specific request. */
|
||||
bool ignoreRequest = false;
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,14 +8,11 @@
|
||||
*/
|
||||
class SinglePortModule : public MeshModule
|
||||
{
|
||||
protected:
|
||||
meshtastic_PortNum ourPortNum;
|
||||
|
||||
public:
|
||||
/** Constructor
|
||||
* name is for debugging output
|
||||
*/
|
||||
SinglePortModule(const char *_name, meshtastic_PortNum _ourPortNum) : MeshModule(_name), ourPortNum(_ourPortNum) {}
|
||||
SinglePortModule(const char *_name, meshtastic_PortNum _ourPortNum) : MeshModule(_name, _ourPortNum) {}
|
||||
|
||||
protected:
|
||||
/**
|
||||
@@ -38,4 +35,4 @@ class SinglePortModule : public MeshModule
|
||||
|
||||
return p;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -109,7 +109,7 @@ bool SerialModule::isValidConfig(const meshtastic_ModuleConfig_SerialConfig &con
|
||||
return true;
|
||||
}
|
||||
|
||||
SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio")
|
||||
SerialModuleRadio::SerialModuleRadio() : SinglePortModule("SerialModuleRadio", meshtastic_PortNum_SERIAL_APP)
|
||||
{
|
||||
switch (moduleConfig.serial.mode) {
|
||||
case meshtastic_ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG:
|
||||
@@ -330,18 +330,6 @@ void SerialModule::sendTelemetry(meshtastic_Telemetry m)
|
||||
service->sendToMesh(p, RX_SRC_LOCAL, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a new mesh packet for use as a reply to a received packet.
|
||||
*
|
||||
* @return A pointer to the newly allocated mesh packet.
|
||||
*/
|
||||
meshtastic_MeshPacket *SerialModuleRadio::allocReply()
|
||||
{
|
||||
auto reply = allocDataPacket(); // Allocate a packet for sending
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a payload to a specified destination node.
|
||||
*
|
||||
@@ -351,7 +339,7 @@ meshtastic_MeshPacket *SerialModuleRadio::allocReply()
|
||||
void SerialModuleRadio::sendPayload(NodeNum dest, bool wantReplies)
|
||||
{
|
||||
const meshtastic_Channel *ch = (boundChannel != NULL) ? &channels.getByName(boundChannel) : NULL;
|
||||
meshtastic_MeshPacket *p = allocReply();
|
||||
meshtastic_MeshPacket *p = allocDataPacket();
|
||||
if (!p)
|
||||
return;
|
||||
p->to = dest;
|
||||
|
||||
@@ -40,7 +40,7 @@ extern SerialModule *serialModule;
|
||||
* Radio interface for SerialModule
|
||||
*
|
||||
*/
|
||||
class SerialModuleRadio : public MeshModule
|
||||
class SerialModuleRadio : public SinglePortModule
|
||||
{
|
||||
uint32_t lastRxID = 0;
|
||||
char outbuf[90] = "";
|
||||
@@ -54,31 +54,14 @@ class SerialModuleRadio : public MeshModule
|
||||
void sendPayload(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
|
||||
|
||||
protected:
|
||||
virtual meshtastic_MeshPacket *allocReply() override;
|
||||
|
||||
/** Called to handle a particular incoming message
|
||||
|
||||
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for
|
||||
it
|
||||
*/
|
||||
virtual ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override;
|
||||
|
||||
meshtastic_PortNum ourPortNum;
|
||||
|
||||
virtual bool wantPacket(const meshtastic_MeshPacket *p) override { return p->decoded.portnum == ourPortNum; }
|
||||
|
||||
meshtastic_MeshPacket *allocDataPacket()
|
||||
{
|
||||
// Update our local node info with our position (even if we don't decide to update anyone else)
|
||||
meshtastic_MeshPacket *p = router->allocForSending();
|
||||
if (!p)
|
||||
return nullptr;
|
||||
p->decoded.portnum = ourPortNum;
|
||||
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
extern SerialModuleRadio *serialModuleRadio;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user