diff --git a/examples/simple_repeater/MyMesh.cpp b/examples/simple_repeater/MyMesh.cpp index 53f642fdf6..f5f96878e8 100644 --- a/examples/simple_repeater/MyMesh.cpp +++ b/examples/simple_repeater/MyMesh.cpp @@ -433,6 +433,15 @@ bool MyMesh::allowPacketForward(const mesh::Packet *packet) { MESH_DEBUG_PRINTLN("allowPacketForward: unknown transport code, or wildcard not allowed for FLOOD 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; + } + if (packet->isRouteFlood() && _prefs.loop_detect != LOOP_DETECT_OFF) { const uint8_t* maximums; if (_prefs.loop_detect == LOOP_DETECT_MINIMAL) { @@ -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 diff --git a/src/helpers/CommonCLI.cpp b/src/helpers/CommonCLI.cpp index b71afc72e2..c6f2c569f5 100644 --- a/src/helpers/CommonCLI.cpp +++ b/src/helpers/CommonCLI.cpp @@ -89,6 +89,8 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) { 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 + file.read((uint8_t *)&_prefs->flood_advert_base, sizeof(_prefs->flood_advert_base)); // 290 + // next: 291 // sanitise bad pref values @@ -119,6 +121,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(); } @@ -181,6 +184,7 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) { 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)); file.close(); } @@ -508,6 +512,15 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep savePrefs(); strcpy(reply, "OK"); } + } 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, "advert.interval ", 16) == 0) { int mins = _atoi(&config[16]); if ((mins > 0 && mins < MIN_LOCAL_ADVERT_INTERVAL) || (mins > 240)) { @@ -752,6 +765,8 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep sprintf(reply, "> %s", _prefs->allow_read_only ? "on" : "off"); } else if (memcmp(config, "flood.advert.interval", 21) == 0) { sprintf(reply, "> %d", ((uint32_t) _prefs->flood_advert_interval)); + } else if (memcmp(config, "flood.advert.base", 17) == 0) { + sprintf(reply, "> %s", StrHelper::ftoa(_prefs->flood_advert_base)); } else if (memcmp(config, "advert.interval", 15) == 0) { sprintf(reply, "> %d", ((uint32_t) _prefs->advert_interval) * 2); } else if (memcmp(config, "guest.password", 14) == 0) { diff --git a/src/helpers/CommonCLI.h b/src/helpers/CommonCLI.h index ffdc7c6536..b2b20621a2 100644 --- a/src/helpers/CommonCLI.h +++ b/src/helpers/CommonCLI.h @@ -61,6 +61,7 @@ struct NodePrefs { // persisted to file uint8_t rx_boosted_gain; // power settings uint8_t path_hash_mode; // which path mode to use when sending uint8_t loop_detect; + float flood_advert_base; }; class CommonCLICallbacks {