Don't show messages from Ignored nodes (#11068)
* Honor Node Ignore messages * Screenless node fix
This commit is contained in:
+108
-21
@@ -7,6 +7,7 @@
|
||||
#include "SafeFile.h"
|
||||
#include "gps/RTC.h"
|
||||
#include "memory/MemAudit.h"
|
||||
#include <cassert>
|
||||
#include <cstring> // memcpy
|
||||
|
||||
#ifndef MESSAGE_TEXT_POOL_SIZE
|
||||
@@ -65,6 +66,15 @@ static inline const char *getTextFromPool(uint16_t offset)
|
||||
return &g_messagePool[offset];
|
||||
}
|
||||
|
||||
static inline bool isIgnoredNodeNum(uint32_t nodeNum)
|
||||
{
|
||||
if (nodeNum == 0 || nodeNum == NODENUM_BROADCAST)
|
||||
return false;
|
||||
|
||||
const meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeNum);
|
||||
return nodeInfoLiteIsIgnored(node);
|
||||
}
|
||||
|
||||
// Helper: assign a timestamp (RTC if available, else boot-relative)
|
||||
static inline void assignTimestamp(StoredMessage &sm)
|
||||
{
|
||||
@@ -163,9 +173,44 @@ static inline void autosaveTick(MessageStore *store)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Add from incoming/outgoing packet
|
||||
const StoredMessage &MessageStore::addFromPacket(const meshtastic_MeshPacket &packet)
|
||||
bool MessageStore::shouldStorePacket(const meshtastic_MeshPacket &packet) const
|
||||
{
|
||||
const uint32_t localNode = nodeDB->getNodeNum();
|
||||
const bool isDM = packet.to != 0 && packet.to != NODENUM_BROADCAST;
|
||||
if (isDM) {
|
||||
const bool outgoing = packet.from == 0 || packet.from == localNode;
|
||||
const uint32_t peer = outgoing ? packet.to : packet.from;
|
||||
return !isIgnoredNodeNum(peer);
|
||||
}
|
||||
|
||||
if (packet.from != 0 && packet.from != localNode)
|
||||
return !isIgnoredNodeNum(packet.from);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MessageStore::isMessageVisible(const StoredMessage &msg) const
|
||||
{
|
||||
const uint32_t localNode = nodeDB->getNodeNum();
|
||||
if (msg.type == MessageType::DM_TO_US) {
|
||||
const uint32_t peer = (msg.sender == localNode) ? msg.dest : msg.sender;
|
||||
return !isIgnoredNodeNum(peer);
|
||||
}
|
||||
|
||||
if (msg.sender != 0 && msg.sender != localNode)
|
||||
return !isIgnoredNodeNum(msg.sender);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Add from incoming/outgoing packet
|
||||
const StoredMessage *MessageStore::tryAddFromPacket(const meshtastic_MeshPacket &packet)
|
||||
{
|
||||
if (!shouldStorePacket(packet)) {
|
||||
LOG_DEBUG("Drop store 0x%08x", packet.from);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StoredMessage sm;
|
||||
assignTimestamp(sm);
|
||||
sm.channelIndex = packet.channel;
|
||||
@@ -196,7 +241,14 @@ const StoredMessage &MessageStore::addFromPacket(const meshtastic_MeshPacket &pa
|
||||
markMessageStoreUnsaved();
|
||||
#endif
|
||||
|
||||
return liveMessages.back();
|
||||
return &liveMessages.back();
|
||||
}
|
||||
|
||||
const StoredMessage &MessageStore::addFromPacket(const meshtastic_MeshPacket &packet)
|
||||
{
|
||||
const StoredMessage *stored = tryAddFromPacket(packet);
|
||||
assert(stored);
|
||||
return *stored;
|
||||
}
|
||||
|
||||
// Outgoing/manual message
|
||||
@@ -323,28 +375,33 @@ void MessageStore::loadFromFlash()
|
||||
resetMessagePool(); // reset pool when loading
|
||||
|
||||
#ifdef FSCom
|
||||
concurrency::LockGuard guard(spiLock);
|
||||
{
|
||||
concurrency::LockGuard guard(spiLock);
|
||||
|
||||
if (!FSCom.exists(filename.c_str()))
|
||||
return;
|
||||
if (!FSCom.exists(filename.c_str()))
|
||||
return;
|
||||
|
||||
auto f = FSCom.open(filename.c_str(), FILE_O_READ);
|
||||
if (!f)
|
||||
return;
|
||||
auto f = FSCom.open(filename.c_str(), FILE_O_READ);
|
||||
if (!f)
|
||||
return;
|
||||
|
||||
uint8_t count = 0;
|
||||
f.readBytes(reinterpret_cast<char *>(&count), 1);
|
||||
if (count > MAX_MESSAGES_SAVED)
|
||||
count = MAX_MESSAGES_SAVED;
|
||||
uint8_t count = 0;
|
||||
f.readBytes(reinterpret_cast<char *>(&count), 1);
|
||||
if (count > MAX_MESSAGES_SAVED)
|
||||
count = MAX_MESSAGES_SAVED;
|
||||
|
||||
for (uint8_t i = 0; i < count; ++i) {
|
||||
StoredMessage m;
|
||||
if (!readMessageRecord(f, m))
|
||||
break;
|
||||
liveMessages.push_back(m);
|
||||
for (uint8_t i = 0; i < count; ++i) {
|
||||
StoredMessage m;
|
||||
if (!readMessageRecord(f, m))
|
||||
break;
|
||||
liveMessages.push_back(m);
|
||||
}
|
||||
|
||||
f.close();
|
||||
}
|
||||
|
||||
f.close();
|
||||
if (pruneHiddenMessages())
|
||||
saveToFlash();
|
||||
#endif
|
||||
// Loading messages does not trigger an autosave
|
||||
g_messageStoreHasUnsavedChanges = false;
|
||||
@@ -406,6 +463,13 @@ template <typename Predicate> static void eraseAllMatches(std::deque<StoredMessa
|
||||
}
|
||||
}
|
||||
|
||||
bool MessageStore::pruneHiddenMessages()
|
||||
{
|
||||
const size_t before = liveMessages.size();
|
||||
eraseAllMatches(liveMessages, [&](const StoredMessage &m) { return !isMessageVisible(m); });
|
||||
return liveMessages.size() != before;
|
||||
}
|
||||
|
||||
// Delete oldest message (RAM + persisted queue)
|
||||
void MessageStore::deleteOldestMessage()
|
||||
{
|
||||
@@ -443,6 +507,20 @@ void MessageStore::deleteAllMessagesWithPeer(uint32_t peer)
|
||||
saveToFlash();
|
||||
}
|
||||
|
||||
void MessageStore::deleteAllMessagesFromNode(uint32_t nodeNum)
|
||||
{
|
||||
const uint32_t local = nodeDB->getNodeNum();
|
||||
auto pred = [&](const StoredMessage &m) {
|
||||
if (m.sender == nodeNum)
|
||||
return true;
|
||||
if (m.type != MessageType::DM_TO_US)
|
||||
return false;
|
||||
return m.sender == local ? m.dest == nodeNum : m.sender == nodeNum;
|
||||
};
|
||||
eraseAllMatches(liveMessages, pred);
|
||||
saveToFlash();
|
||||
}
|
||||
|
||||
// Delete oldest message in a direct chat with a node
|
||||
void MessageStore::deleteOldestMessageWithPeer(uint32_t peer)
|
||||
{
|
||||
@@ -460,7 +538,7 @@ std::deque<StoredMessage> MessageStore::getChannelMessages(uint8_t channel) cons
|
||||
{
|
||||
std::deque<StoredMessage> result;
|
||||
for (const auto &m : liveMessages) {
|
||||
if (m.type == MessageType::BROADCAST && m.channelIndex == channel) {
|
||||
if (isMessageVisible(m) && m.type == MessageType::BROADCAST && m.channelIndex == channel) {
|
||||
result.push_back(m);
|
||||
}
|
||||
}
|
||||
@@ -471,13 +549,22 @@ std::deque<StoredMessage> MessageStore::getDirectMessages() const
|
||||
{
|
||||
std::deque<StoredMessage> result;
|
||||
for (const auto &m : liveMessages) {
|
||||
if (m.type == MessageType::DM_TO_US) {
|
||||
if (isMessageVisible(m) && m.type == MessageType::DM_TO_US) {
|
||||
result.push_back(m);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool MessageStore::hasVisibleMessages() const
|
||||
{
|
||||
for (const auto &m : liveMessages) {
|
||||
if (isMessageVisible(m))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Upgrade boot-relative timestamps once RTC is valid
|
||||
// Only same-boot boot-relative messages are healed.
|
||||
// Persisted boot-relative messages from old boots stay ??? forever.
|
||||
|
||||
+6
-2
@@ -93,7 +93,7 @@ class MessageStore
|
||||
void addLiveMessage(StoredMessage &&msg);
|
||||
void addLiveMessage(const StoredMessage &msg); // convenience overload
|
||||
const std::deque<StoredMessage> &getLiveMessages() const { return liveMessages; }
|
||||
|
||||
const StoredMessage *tryAddFromPacket(const meshtastic_MeshPacket &mp); // Incoming/outgoing -> RAM only
|
||||
// Add new messages from packets or manual input
|
||||
const StoredMessage &addFromPacket(const meshtastic_MeshPacket &mp); // Incoming/outgoing → RAM only
|
||||
void addFromString(uint32_t sender, uint8_t channelIndex, const std::string &text); // Manual add
|
||||
@@ -111,13 +111,16 @@ class MessageStore
|
||||
void deleteOldestMessageWithPeer(uint32_t peer);
|
||||
void deleteAllMessagesInChannel(uint8_t channel);
|
||||
void deleteAllMessagesWithPeer(uint32_t peer);
|
||||
|
||||
void deleteAllMessagesFromNode(uint32_t nodeNum);
|
||||
// Unified accessor (for UI code, defaults to RAM buffer)
|
||||
const std::deque<StoredMessage> &getMessages() const { return liveMessages; }
|
||||
bool hasVisibleMessages() const;
|
||||
|
||||
// Helper filters for future use
|
||||
std::deque<StoredMessage> getChannelMessages(uint8_t channel) const; // Only broadcast messages on a channel
|
||||
std::deque<StoredMessage> getDirectMessages() const; // Only direct messages
|
||||
bool shouldStorePacket(const meshtastic_MeshPacket &mp) const;
|
||||
bool isMessageVisible(const StoredMessage &msg) const;
|
||||
|
||||
// Upgrade boot-relative timestamps once RTC is valid
|
||||
void upgradeBootRelativeTimestamps();
|
||||
@@ -129,6 +132,7 @@ class MessageStore
|
||||
static uint16_t storeText(const char *src, size_t len);
|
||||
|
||||
private:
|
||||
bool pruneHiddenMessages();
|
||||
std::deque<StoredMessage> liveMessages; // Single in-RAM message buffer (also used for persistence)
|
||||
std::string filename; // Flash filename for persistence
|
||||
};
|
||||
|
||||
@@ -2110,7 +2110,7 @@ int Screen::handleInputEvent(const InputEvent *event)
|
||||
if (ui->getUiState()->currentFrame == framesetInfo.positions.textMessage) {
|
||||
|
||||
if (event->inputEvent == INPUT_BROKER_UP) {
|
||||
if (messageStore.getMessages().empty()) {
|
||||
if (!messageStore.hasVisibleMessages()) {
|
||||
cannedMessageModule->LaunchWithDestination(NODENUM_BROADCAST);
|
||||
} else {
|
||||
graphics::MessageRenderer::scrollUp();
|
||||
@@ -2120,7 +2120,7 @@ int Screen::handleInputEvent(const InputEvent *event)
|
||||
}
|
||||
|
||||
if (event->inputEvent == INPUT_BROKER_DOWN) {
|
||||
if (messageStore.getMessages().empty()) {
|
||||
if (!messageStore.hasVisibleMessages()) {
|
||||
cannedMessageModule->LaunchWithDestination(NODENUM_BROADCAST);
|
||||
} else {
|
||||
graphics::MessageRenderer::scrollDown();
|
||||
@@ -2169,9 +2169,9 @@ int Screen::handleInputEvent(const InputEvent *event)
|
||||
if (!inputIntercepted) {
|
||||
#if defined(INPUTDRIVER_ENCODER_TYPE) && INPUTDRIVER_ENCODER_TYPE == 2
|
||||
bool handledEncoderScroll = false;
|
||||
const bool isTextMessageFrame = (framesetInfo.positions.textMessage != 255 &&
|
||||
this->ui->getUiState()->currentFrame == framesetInfo.positions.textMessage &&
|
||||
!messageStore.getMessages().empty());
|
||||
const bool isTextMessageFrame =
|
||||
(framesetInfo.positions.textMessage != 255 &&
|
||||
this->ui->getUiState()->currentFrame == framesetInfo.positions.textMessage && messageStore.hasVisibleMessages());
|
||||
if (isTextMessageFrame) {
|
||||
if (event->inputEvent == INPUT_BROKER_UP_LONG) {
|
||||
graphics::MessageRenderer::nudgeScroll(-1);
|
||||
@@ -2254,7 +2254,7 @@ int Screen::handleInputEvent(const InputEvent *event)
|
||||
} else if (this->ui->getUiState()->currentFrame == framesetInfo.positions.lora) {
|
||||
menuHandler::loraMenu();
|
||||
} else if (this->ui->getUiState()->currentFrame == framesetInfo.positions.textMessage) {
|
||||
if (!messageStore.getMessages().empty()) {
|
||||
if (messageStore.hasVisibleMessages()) {
|
||||
menuHandler::messageResponseMenu();
|
||||
} else {
|
||||
if (currentResolution == ScreenResolution::UltraLow) {
|
||||
|
||||
@@ -70,12 +70,15 @@ const StoredMessage *getNewestMessageForActiveThread()
|
||||
const uint32_t peer = graphics::MessageRenderer::getThreadPeer();
|
||||
const uint32_t localNode = nodeDB->getNodeNum();
|
||||
|
||||
if (mode == graphics::MessageRenderer::ThreadMode::ALL) {
|
||||
return &messages.back();
|
||||
}
|
||||
|
||||
for (auto it = messages.rbegin(); it != messages.rend(); ++it) {
|
||||
const StoredMessage &m = *it;
|
||||
if (!messageStore.isMessageVisible(m)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mode == graphics::MessageRenderer::ThreadMode::ALL) {
|
||||
return &m;
|
||||
}
|
||||
|
||||
if (mode == graphics::MessageRenderer::ThreadMode::CHANNEL) {
|
||||
if (m.type == MessageType::BROADCAST && static_cast<int>(m.channelIndex) == channel) {
|
||||
|
||||
@@ -403,6 +403,8 @@ void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
||||
// Filter messages based on thread mode
|
||||
std::deque<StoredMessage> filtered;
|
||||
for (const auto &m : messageStore.getLiveMessages()) {
|
||||
if (!messageStore.isMessageVisible(m))
|
||||
continue;
|
||||
bool include = false;
|
||||
switch (currentMode) {
|
||||
case ThreadMode::ALL:
|
||||
|
||||
@@ -234,7 +234,8 @@ std::string InkHUD::NotificationApplet::getNotificationText(uint16_t widthAvaila
|
||||
// Pick source of message
|
||||
const StoredMessage *message =
|
||||
msgIsBroadcast ? &inkhud->persistence->latestMessage.broadcast : &inkhud->persistence->latestMessage.dm;
|
||||
|
||||
if (!message->sender || !messageStore.isMessageVisible(*message))
|
||||
return parse(text);
|
||||
// Find info about the sender
|
||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(message->sender);
|
||||
|
||||
@@ -270,4 +271,4 @@ std::string InkHUD::NotificationApplet::getNotificationText(uint16_t widthAvaila
|
||||
return parse(text);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -46,7 +46,7 @@ void InkHUD::AllMessageApplet::onRender(bool full)
|
||||
message = &latestMessage->dm;
|
||||
|
||||
// Short circuit: no text message
|
||||
if (!message->sender) {
|
||||
if (!message->sender || !messageStore.isMessageVisible(*message)) {
|
||||
printAt(X(0.5), Y(0.5), "No Message", CENTER, MIDDLE);
|
||||
return;
|
||||
}
|
||||
@@ -138,4 +138,4 @@ bool InkHUD::AllMessageApplet::approveNotification(Notification &n)
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -42,7 +42,7 @@ int InkHUD::DMApplet::onReceiveTextMessage(const meshtastic_MeshPacket *p)
|
||||
void InkHUD::DMApplet::onRender(bool full)
|
||||
{
|
||||
// Abort if no text message
|
||||
if (!latestMessage->dm.sender) {
|
||||
if (!latestMessage->dm.sender || !messageStore.isMessageVisible(latestMessage->dm)) {
|
||||
printAt(X(0.5), Y(0.5), "No DMs", CENTER, MIDDLE);
|
||||
return;
|
||||
}
|
||||
@@ -131,4 +131,4 @@ bool InkHUD::DMApplet::approveNotification(Notification &n)
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -191,7 +191,8 @@ ProcessMessage InkHUD::ThreadedMessageApplet::handleReceived(const meshtastic_Me
|
||||
return ProcessMessage::CONTINUE;
|
||||
|
||||
// Store in the global messageStore - this handles sender, timestamp, channel, text, and ack status
|
||||
messageStore.addFromPacket(mp);
|
||||
if (!messageStore.tryAddFromPacket(mp))
|
||||
return ProcessMessage::CONTINUE;
|
||||
|
||||
// If this was an incoming message, suggest that our applet becomes foreground, if permitted
|
||||
if (getFrom(&mp) != nodeDB->getNodeNum())
|
||||
|
||||
@@ -534,13 +534,19 @@ int InkHUD::Events::onReceiveTextMessage(const meshtastic_MeshPacket *packet)
|
||||
if (getFrom(packet) == nodeDB->getNodeNum())
|
||||
return 0;
|
||||
|
||||
if (!messageStore.shouldStorePacket(*packet))
|
||||
return 0;
|
||||
|
||||
bool isBroadcastMsg = isBroadcast(packet->to);
|
||||
inkhud->persistence->latestMessage.wasBroadcast = isBroadcastMsg;
|
||||
|
||||
if (!isBroadcastMsg) {
|
||||
// DMs never pass through ThreadedMessageApplet, so add them to the global store here
|
||||
// so they survive reboots. Derive the latestMessage cache entry from the stored result.
|
||||
inkhud->persistence->latestMessage.dm = messageStore.addFromPacket(*packet);
|
||||
const StoredMessage *stored = messageStore.tryAddFromPacket(*packet);
|
||||
if (!stored)
|
||||
return 0;
|
||||
inkhud->persistence->latestMessage.dm = *stored;
|
||||
} else {
|
||||
// Broadcasts are added to the global store by ThreadedMessageApplet::handleReceived().
|
||||
// Here we only update the latestMessage cache used by AllMessageApplet / NotificationApplet.
|
||||
|
||||
@@ -26,6 +26,10 @@ void InkHUD::Persistence::loadLatestMessage()
|
||||
|
||||
int lastBroadcastPos = -1, lastDMPos = -1, pos = 0;
|
||||
for (const StoredMessage &m : messageStore.getLiveMessages()) {
|
||||
if (!messageStore.isMessageVisible(m)) {
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
if (m.type == MessageType::BROADCAST) {
|
||||
latestMessage.broadcast = m;
|
||||
lastBroadcastPos = pos;
|
||||
|
||||
@@ -257,8 +257,8 @@ void MeshService::handleToRadio(meshtastic_MeshPacket &p)
|
||||
p.to != NODENUM_BROADCAST && p.to != 0) // DM only
|
||||
{
|
||||
perhapsDecode(&p);
|
||||
const StoredMessage &sm = messageStore.addFromPacket(p);
|
||||
graphics::MessageRenderer::handleNewMessage(nullptr, sm, p); // notify UI
|
||||
if (const StoredMessage *sm = messageStore.tryAddFromPacket(p))
|
||||
graphics::MessageRenderer::handleNewMessage(nullptr, *sm, p); // notify UI
|
||||
})
|
||||
#if !MESHTASTIC_EXCLUDE_ADMIN
|
||||
// Note admin requests on their way out: AdminModule only accepts a response from a remote we
|
||||
|
||||
@@ -3268,6 +3268,9 @@ void NodeDB::addFromContact(meshtastic_SharedContact contact)
|
||||
LOG_WARN(PROTECTED_CAP_WARN_FMT, "ignore", contact.node_num, MAX_NUM_NODES - 2);
|
||||
nodeInfoLiteSetBit(info, NODEINFO_BITFIELD_IS_FAVORITE_MASK, false);
|
||||
eraseNodeSatellites(contact.node_num);
|
||||
#if HAS_SCREEN || defined(MESHTASTIC_INCLUDE_NICHE_GRAPHICS)
|
||||
messageStore.deleteAllMessagesFromNode(contact.node_num);
|
||||
#endif
|
||||
} else {
|
||||
/* Clients are sending add_contact before every text message DM (because clients may hold a larger node database with
|
||||
* public keys than the radio holds). However, we don't want to update last_heard just because we sent someone a DM!
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "Default.h"
|
||||
#include "MeshRadio.h"
|
||||
#include "MessageStore.h"
|
||||
#include "RadioInterface.h"
|
||||
#include "TypeConversions.h"
|
||||
#include "mesh/RadioLibInterface.h"
|
||||
@@ -537,7 +538,14 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
if (node != NULL) {
|
||||
if (nodeDB->setProtectedFlag(node, NODEINFO_BITFIELD_IS_IGNORED_MASK, true)) {
|
||||
nodeDB->eraseNodeSatellites(node->num);
|
||||
#if HAS_SCREEN || defined(MESHTASTIC_INCLUDE_NICHE_GRAPHICS)
|
||||
messageStore.deleteAllMessagesFromNode(node->num);
|
||||
#endif
|
||||
saveChanges(SEGMENT_NODEDATABASE, false);
|
||||
#if HAS_SCREEN
|
||||
if (screen)
|
||||
screen->setFrames(graphics::Screen::FOCUS_PRESERVE);
|
||||
#endif
|
||||
} else if (mp.from == 0) { // local request from the phone - tell the user why it didn't take
|
||||
sendWarning(NodeDB::PROTECTED_CAP_WARN_FMT, "ignore", r->set_ignored_node, MAX_NUM_NODES - 2);
|
||||
} else {
|
||||
|
||||
@@ -25,12 +25,14 @@ ProcessMessage TextMessageModule::handleReceived(const meshtastic_MeshPacket &mp
|
||||
// Guard against running in MeshtasticUI or with no screen
|
||||
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
|
||||
// Store in the central message history
|
||||
const StoredMessage &sm = messageStore.addFromPacket(mp);
|
||||
const StoredMessage *sm = messageStore.tryAddFromPacket(mp);
|
||||
if (!sm)
|
||||
return ProcessMessage::CONTINUE;
|
||||
|
||||
// Pass message to renderer (banner + thread switching + scroll reset)
|
||||
// Use the global Screen singleton to retrieve the current OLED display
|
||||
auto *display = screen ? screen->getDisplayDevice() : nullptr;
|
||||
graphics::MessageRenderer::handleNewMessage(display, sm, mp);
|
||||
graphics::MessageRenderer::handleNewMessage(display, *sm, mp);
|
||||
})
|
||||
// Only trigger screen wake if configuration allows it
|
||||
if (shouldWakeOnReceivedMessage()) {
|
||||
|
||||
@@ -55,6 +55,32 @@ static bool isConnected = false;
|
||||
static uint32_t lastPositionUnavailableWarning = 0;
|
||||
static const uint32_t POSITION_UNAVAILABLE_WARNING_INTERVAL_MS = 15000; // 15 seconds
|
||||
|
||||
inline bool shouldDropMqttDownlink(const meshtastic_MeshPacket &packet)
|
||||
{
|
||||
if (is_in_repeated(config.lora.ignore_incoming, packet.from)) {
|
||||
LOG_INFO("Drop MQTT ignored 0x%08x", packet.from);
|
||||
return true;
|
||||
}
|
||||
|
||||
const meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(packet.from);
|
||||
if (nodeInfoLiteIsIgnored(node)) {
|
||||
LOG_INFO("Drop MQTT node 0x%08x", packet.from);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (packet.from == NODENUM_BROADCAST) {
|
||||
LOG_INFO("Drop MQTT broadcast src");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (config.lora.ignore_mqtt) {
|
||||
LOG_INFO("Drop MQTT ignore_mqtt");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void onReceiveProto(char *topic, byte *payload, size_t length)
|
||||
{
|
||||
const DecodedServiceEnvelope e(payload, length);
|
||||
@@ -122,6 +148,9 @@ inline void onReceiveProto(char *topic, byte *payload, size_t length)
|
||||
p->which_payload_variant = e.packet->which_payload_variant;
|
||||
memcpy(&p->decoded, &e.packet->decoded, std::max(sizeof(p->decoded), sizeof(p->encrypted)));
|
||||
|
||||
if (shouldDropMqttDownlink(*p))
|
||||
return;
|
||||
|
||||
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
||||
if (moduleConfig.mqtt.encryption_enabled) {
|
||||
LOG_INFO("Ignore decoded message on MQTT, encryption is enabled");
|
||||
|
||||
Reference in New Issue
Block a user