diff --git a/docs/cli_commands.md b/docs/cli_commands.md index 4a203f160a..06b7f4c85a 100644 --- a/docs/cli_commands.md +++ b/docs/cli_commands.md @@ -442,7 +442,24 @@ This document provides an overview of CLI commands that can be sent to MeshCore **Note:** the 'path.hash.mode' sets the low-level ID/hash encoding size used when the repeater adverts. This setting has no impact on what packet ID/hash size this repeater forwards, all sizes should be forwarded on firmware >= 1.14. This feature was added in firmware 1.14 -**Temporary Note:** adverts with ID/hash sizes of 2 or 3 bytes may have limited flood propagation in your network while this feature is new as v1.13.0 firmware and older will drop packets with multibyte path ID/hashes as only 1-byte hashes are supported. Consider your install base of firmware >=1.14 has reached a criticality for effective network flooding before implementing higher ID/hash sizes. +**Temporary Note:** adverts with ID/hash sizes of 2 or 3 bytes may have limited flood propagation in your network while this feature is new as v1.13.0 firmware and older will drop packets with multibyte path ID/hashes as only 1-byte hashes are supported. Consider your install base of firmware >=1.14 has reached a criticality for effective network flooding before implementing higher ID/hash sizes. + +--- + +#### View or change minimum path hash size for forwarded packets (repeaters only) +**Usage:** +- `get path.hash.mode.min` +- `set path.hash.mode.min ` + +**Parameters:** +- `value`: Minimum path hash mode (0-2) + - `0`: No minimum (forward all packets) + - `1`: Require hash size >= 2 bytes (drop 1-byte hashes) + - `2`: Require hash size >= 3 bytes (drop 1-2 byte hashes) + +**Default:** `0` + +**Note:** This setting only applies to repeaters and only affects flood packet forwarding. When set to a non-zero value, the repeater will drop flood packets whose embedded path hash size is smaller than the minimum. --- diff --git a/docs/faq.md b/docs/faq.md index f82d3c9fdc..e2984890da 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -299,7 +299,12 @@ However, with 1 byte, there are only 254 unique IDs (exclude 00 and FF which are Firmware version 1.14 and newer introduces the ability for repeaters to advert with 1-, 2-, or 3-byte adverts. Companions can also send out channel and direct messages with 1-, 2-, or 3-byte path. Adverts and messages sent in 1-byte path is compatible with repeater firmware older or newer than 1.14. They will travel up to 64 hops. 2-byte adverts and messages will travel up to 32 hops. 3-byte adverts and messages will travel up to 21 hops. ### 3.9.1. Q: **What path hash sizes will my repeater forward?** -Repeaters running firmware 1.14+ repeat packets sent with 1-, 2-, or 3-byte path hash. Repeaters on firmware older than 1.14 only repeat 1-byte path hash packets and silently drop 2- and 3-byte packets. +Repeaters running firmware 1.14+ repeat packets sent with 1-, 2-, or 3-byte path hash by default. Repeaters on firmware older than 1.14 only repeat 1-byte path hash packets and silently drop 2- and 3-byte packets. + +Repeaters can optionally enforce a minimum path hash size using the `set path.hash.mode.min ` CLI command: +- `0`: No minimum (forward all packets, default) +- `1`: Require hash size >= 2 bytes (drop 1-byte packets) +- `2`: Require hash size >= 3 bytes (drop 1-2 byte packets) ### 3.9.2. Q: **What determines a packet's path hash size?** The original packet sender determines the path hash size. The most common original sender is a companion app. The other common original sender is a repeater, when it broadcasts its advert. diff --git a/examples/simple_repeater/MyMesh.cpp b/examples/simple_repeater/MyMesh.cpp index 096907494b..0214ababbd 100644 --- a/examples/simple_repeater/MyMesh.cpp +++ b/examples/simple_repeater/MyMesh.cpp @@ -432,6 +432,7 @@ bool MyMesh::allowPacketForward(const mesh::Packet *packet) { if (packet->getPathHashCount() >= _prefs.flood_max) return false; if (packet->getRouteType() == ROUTE_TYPE_FLOOD && packet->getPathHashCount() >= _prefs.flood_max_unscoped) return false; if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->getPathHashCount() >= _prefs.flood_max_advert) return false; + if (packet->getPathHashSize() < (_prefs.min_path_hash_mode + 1)) return false; } if (packet->isRouteFlood() && recv_pkt_region == NULL) { MESH_DEBUG_PRINTLN("allowPacketForward: unknown transport code, or wildcard not allowed for FLOOD packet"); @@ -892,6 +893,7 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc _prefs.flood_max = 64; _prefs.flood_max_unscoped = 64; _prefs.flood_max_advert = 8; + _prefs.min_path_hash_mode = 0; // default minimum (mode 0 = hash_size 1) _prefs.interference_threshold = 0; // disabled // bridge defaults diff --git a/src/helpers/CommonCLI.cpp b/src/helpers/CommonCLI.cpp index b78ad6ebd6..2e09ed8d4c 100644 --- a/src/helpers/CommonCLI.cpp +++ b/src/helpers/CommonCLI.cpp @@ -91,7 +91,8 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) { file.read((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 290 file.read((uint8_t *)&_prefs->flood_max_unscoped, sizeof(_prefs->flood_max_unscoped)); // 291 file.read((uint8_t *)&_prefs->flood_max_advert, sizeof(_prefs->flood_max_advert)); // 292 - // next: 293 + file.read((uint8_t *)&_prefs->min_path_hash_mode, sizeof(_prefs->min_path_hash_mode)); // 293 + // next: 294 // sanitise bad pref values _prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f); @@ -184,7 +185,8 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) { file.write((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 290 file.write((uint8_t *)&_prefs->flood_max_unscoped, sizeof(_prefs->flood_max_unscoped)); // 291 file.write((uint8_t *)&_prefs->flood_max_advert, sizeof(_prefs->flood_max_advert)); // 292 - // next: 293 + file.write((uint8_t *)&_prefs->min_path_hash_mode, sizeof(_prefs->min_path_hash_mode)); // 293 + // next: 294 file.close(); } @@ -668,6 +670,15 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep } else { strcpy(reply, "Error, must be 0,1, or 2"); } + } else if (memcmp(config, "path.hash.mode.min ", 19) == 0) { + uint8_t mode = atoi(&config[19]); + if (mode < 3) { + _prefs->min_path_hash_mode = mode; + savePrefs(); + strcpy(reply, "OK"); + } else { + strcpy(reply, "Error, must be 0,1, or 2"); + } } else if (memcmp(config, "loop.detect ", 12) == 0) { config += 12; uint8_t mode; @@ -832,6 +843,8 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep sp++; } *reply = 0; // set null terminator + } else if (memcmp(config, "path.hash.mode.min", 18) == 0) { + sprintf(reply, "> %d", (uint32_t)_prefs->min_path_hash_mode); } else if (memcmp(config, "path.hash.mode", 14) == 0) { sprintf(reply, "> %d", (uint32_t)_prefs->path_hash_mode); } else if (memcmp(config, "loop.detect", 11) == 0) { diff --git a/src/helpers/CommonCLI.h b/src/helpers/CommonCLI.h index b509c2b31a..7b65825084 100644 --- a/src/helpers/CommonCLI.h +++ b/src/helpers/CommonCLI.h @@ -62,6 +62,7 @@ struct NodePrefs { // persisted to file char owner_info[120]; uint8_t rx_boosted_gain; // power settings uint8_t path_hash_mode; // which path mode to use when sending + uint8_t min_path_hash_mode; // minimum path hash size to forward (0=disabled) uint8_t loop_detect; };