Integration of upstrem PR #1338

This commit is contained in:
Matthias Wientapper
2026-04-24 21:35:51 +02:00
5 changed files with 54 additions and 5 deletions

View File

@@ -1,3 +1,18 @@
## About MeshCore-Evo
This is a friendly fork of the MeshCore project.
Its aim is to provide repeater firmwares with a few additional pending upstream PRs/improvements (i.e. PRs/improvements that are available to the MeshCore project but have not yet been merged in the upstream repo or PRs that might never be merged upstream for some reason).
These changes are intended to help mitigating challenges in big or dense meshes, e.g.:
- Dealing with flood advert traffic
- improving `denyf *` handling
This list might change any time.
Refer to the [release notes](https://github.com/mattzzw/MeshCore-Evo/releases) for an up-to-date list of the applied changes.
## About MeshCore
MeshCore is a lightweight, portable C++ library that enables multi-hop packet routing for embedded projects using LoRa and other packet radios. It is designed for developers who want to create resilient, decentralized communication networks that work without the internet.

View File

@@ -447,6 +447,15 @@ bool MyMesh::allowPacketForward(const mesh::Packet *packet) {
return false;
}
}
// Limit flood advert paket forwarding using a probabilistic reduction defined by P(h) = 0.308^(hops-1)
// https://github.com/meshcore-dev/MeshCore/issues/1223
if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->isRouteFlood()) {
double roll_dice = (double)rand() / RAND_MAX;
double forw_prob = pow(_prefs.flood_advert_base, packet->path_len - 1);
if (roll_dice > forw_prob)
return false;
}
return true;
}
@@ -885,6 +894,7 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
_prefs.tx_power_dbm = LORA_TX_POWER;
_prefs.advert_interval = 1; // default to 2 minutes for NEW installs
_prefs.flood_advert_interval = 12; // 12 hours
_prefs.flood_advert_base = 0.308f;
_prefs.flood_max = 64;
_prefs.interference_threshold = 0; // disabled

View File

@@ -282,7 +282,17 @@ uint32_t MyMesh::getDirectRetransmitDelay(const mesh::Packet *packet) {
bool MyMesh::allowPacketForward(const mesh::Packet *packet) {
if (_prefs.disable_fwd) return false;
if (packet->isRouteFlood() && packet->getPathHashCount() >= _prefs.flood_max) return false;
if (packet->isRouteFlood() && packet->path_len >= _prefs.flood_max) return false;
// Limit flood advert packet forwarding using a probabilistic reduction defined by P(h) = base^(hops-1)
// https://github.com/meshcore-dev/MeshCore/issues/1223
if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->isRouteFlood()) {
double roll_dice = (double)rand() / RAND_MAX;
double forw_prob = pow(_prefs.flood_advert_base, packet->path_len - 1);
if (roll_dice > forw_prob)
return false;
}
return true;
}
@@ -642,6 +652,7 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
_prefs.disable_fwd = 1;
_prefs.advert_interval = 1; // default to 2 minutes for NEW installs
_prefs.flood_advert_interval = 12; // 12 hours
_prefs.flood_advert_base = 0.308f;
_prefs.flood_max = 64;
_prefs.interference_threshold = 0; // disabled
#ifdef ROOM_PASSWORD

View File

@@ -88,8 +88,8 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
file.read((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162
file.read((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166
file.read((uint8_t *)_prefs->owner_info, sizeof(_prefs->owner_info)); // 170
file.read((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 290
// next: 291
file.read((uint8_t *)&_prefs->flood_advert_base, sizeof(_prefs->flood_advert_base)); // 290
file.read((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 294
// sanitise bad pref values
_prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f);
@@ -119,6 +119,7 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
// sanitise settings
_prefs->rx_boosted_gain = constrain(_prefs->rx_boosted_gain, 0, 1); // boolean
_prefs->flood_advert_base = constrain(_prefs->flood_advert_base, 0, 1);
file.close();
}
@@ -179,8 +180,8 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
file.write((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162
file.write((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166
file.write((uint8_t *)_prefs->owner_info, sizeof(_prefs->owner_info)); // 170
file.write((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 290
// next: 291
file.write((uint8_t *)&_prefs->flood_advert_base, sizeof(_prefs->flood_advert_base)); // 290
file.write((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 294
file.close();
}
@@ -607,6 +608,15 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep
} else {
strcpy(reply, "Error, max 64");
}
} else if (memcmp(config, "flood.advert.base ", 18) == 0) {
float f = atof(&config[18]);
if (f >= 0.0f && f <= 1.0f) {
_prefs->flood_advert_base = f;
savePrefs();
strcpy(reply, "OK");
} else {
strcpy(reply, "Error: base must be between 0 and 1");
}
} else if (memcmp(config, "direct.txdelay ", 15) == 0) {
float f = atof(&config[15]);
if (f >= 0) {
@@ -784,6 +794,8 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->tx_delay_factor));
} else if (memcmp(config, "flood.max", 9) == 0) {
sprintf(reply, "> %d", (uint32_t)_prefs->flood_max);
} else if (memcmp(config, "flood.advert.base", 17) == 0) {
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->flood_advert_base));
} else if (memcmp(config, "direct.txdelay", 14) == 0) {
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->direct_tx_delay_factor));
} else if (memcmp(config, "owner.info", 10) == 0) {

View File

@@ -42,6 +42,7 @@ struct NodePrefs { // persisted to file
uint8_t flood_max;
uint8_t interference_threshold;
uint8_t agc_reset_interval; // secs / 4
float flood_advert_base;
// Bridge settings
uint8_t bridge_enabled; // boolean
uint16_t bridge_delay; // milliseconds (default 500 ms)