* repeater: new "get/set loop.detect {off | minimal | moderate | strict }"
This commit is contained in:
@@ -396,6 +396,23 @@ File MyMesh::openAppend(const char *fname) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t max_loop_minimal[] = { 0, /* 1-byte */ 4, /* 2-byte */ 2, /* 3-byte */ 1 };
|
||||||
|
static uint8_t max_loop_moderate[] = { 0, /* 1-byte */ 2, /* 2-byte */ 1, /* 3-byte */ 1 };
|
||||||
|
static uint8_t max_loop_strict[] = { 0, /* 1-byte */ 1, /* 2-byte */ 1, /* 3-byte */ 1 };
|
||||||
|
|
||||||
|
bool MyMesh::isLooped(const mesh::Packet* packet, const uint8_t max_counters[]) {
|
||||||
|
uint8_t hash_size = packet->getPathHashSize();
|
||||||
|
uint8_t hash_count = packet->getPathHashCount();
|
||||||
|
uint8_t n = 0;
|
||||||
|
const uint8_t* path = packet->path;
|
||||||
|
while (hash_count > 0) { // count how many times this node is already in the path
|
||||||
|
if (self_id.isHashMatch(path, hash_size)) n++;
|
||||||
|
hash_count--;
|
||||||
|
path += hash_size;
|
||||||
|
}
|
||||||
|
return n >= max_counters[hash_size];
|
||||||
|
}
|
||||||
|
|
||||||
bool MyMesh::allowPacketForward(const mesh::Packet *packet) {
|
bool MyMesh::allowPacketForward(const mesh::Packet *packet) {
|
||||||
if (_prefs.disable_fwd) return false;
|
if (_prefs.disable_fwd) return false;
|
||||||
if (packet->isRouteFlood() && packet->getPathHashCount() >= _prefs.flood_max) return false;
|
if (packet->isRouteFlood() && packet->getPathHashCount() >= _prefs.flood_max) return false;
|
||||||
@@ -403,6 +420,20 @@ bool MyMesh::allowPacketForward(const mesh::Packet *packet) {
|
|||||||
MESH_DEBUG_PRINTLN("allowPacketForward: unknown transport code, or wildcard not allowed for FLOOD packet");
|
MESH_DEBUG_PRINTLN("allowPacketForward: unknown transport code, or wildcard not allowed for FLOOD packet");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (packet->isRouteFlood() && _prefs.loop_detect != LOOP_DETECT_OFF) {
|
||||||
|
const uint8_t* maximums;
|
||||||
|
if (_prefs.loop_detect == LOOP_DETECT_MINIMAL) {
|
||||||
|
maximums = max_loop_minimal;
|
||||||
|
} else if (_prefs.loop_detect == LOOP_DETECT_MINIMAL) {
|
||||||
|
maximums = max_loop_moderate;
|
||||||
|
} else {
|
||||||
|
maximums = max_loop_strict;
|
||||||
|
}
|
||||||
|
if (isLooped(packet, maximums)) {
|
||||||
|
MESH_DEBUG_PRINTLN("allowPacketForward: FLOOD packet loop detected!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
|
|||||||
mesh::Packet* createSelfAdvert();
|
mesh::Packet* createSelfAdvert();
|
||||||
|
|
||||||
File openAppend(const char* fname);
|
File openAppend(const char* fname);
|
||||||
|
bool isLooped(const mesh::Packet* packet, const uint8_t max_counters[]);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float getAirtimeBudgetFactor() const override {
|
float getAirtimeBudgetFactor() const override {
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
|||||||
file.read((uint8_t *)&_prefs->bw, sizeof(_prefs->bw)); // 116
|
file.read((uint8_t *)&_prefs->bw, sizeof(_prefs->bw)); // 116
|
||||||
file.read((uint8_t *)&_prefs->agc_reset_interval, sizeof(_prefs->agc_reset_interval)); // 120
|
file.read((uint8_t *)&_prefs->agc_reset_interval, sizeof(_prefs->agc_reset_interval)); // 120
|
||||||
file.read((uint8_t *)&_prefs->path_hash_mode, sizeof(_prefs->path_hash_mode)); // 121
|
file.read((uint8_t *)&_prefs->path_hash_mode, sizeof(_prefs->path_hash_mode)); // 121
|
||||||
file.read(pad, 2); // 122
|
file.read((uint8_t *)&_prefs->loop_detect, sizeof(_prefs->loop_detect)); // 122
|
||||||
|
file.read(pad, 1); // 123
|
||||||
file.read((uint8_t *)&_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
|
file.read((uint8_t *)&_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
|
||||||
file.read((uint8_t *)&_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval)); // 125
|
file.read((uint8_t *)&_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval)); // 125
|
||||||
file.read((uint8_t *)&_prefs->interference_threshold, sizeof(_prefs->interference_threshold)); // 126
|
file.read((uint8_t *)&_prefs->interference_threshold, sizeof(_prefs->interference_threshold)); // 126
|
||||||
@@ -150,7 +151,8 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
|
|||||||
file.write((uint8_t *)&_prefs->bw, sizeof(_prefs->bw)); // 116
|
file.write((uint8_t *)&_prefs->bw, sizeof(_prefs->bw)); // 116
|
||||||
file.write((uint8_t *)&_prefs->agc_reset_interval, sizeof(_prefs->agc_reset_interval)); // 120
|
file.write((uint8_t *)&_prefs->agc_reset_interval, sizeof(_prefs->agc_reset_interval)); // 120
|
||||||
file.write((uint8_t *)&_prefs->path_hash_mode, sizeof(_prefs->path_hash_mode)); // 121
|
file.write((uint8_t *)&_prefs->path_hash_mode, sizeof(_prefs->path_hash_mode)); // 121
|
||||||
file.write(pad, 2); // 122
|
file.write((uint8_t *)&_prefs->loop_detect, sizeof(_prefs->loop_detect)); // 122
|
||||||
|
file.write(pad, 1); // 123
|
||||||
file.write((uint8_t *)&_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
|
file.write((uint8_t *)&_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
|
||||||
file.write((uint8_t *)&_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval)); // 125
|
file.write((uint8_t *)&_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval)); // 125
|
||||||
file.write((uint8_t *)&_prefs->interference_threshold, sizeof(_prefs->interference_threshold)); // 126
|
file.write((uint8_t *)&_prefs->interference_threshold, sizeof(_prefs->interference_threshold)); // 126
|
||||||
@@ -334,6 +336,16 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
|||||||
*reply = 0; // set null terminator
|
*reply = 0; // set null terminator
|
||||||
} else if (memcmp(config, "path.hash.mode", 14) == 0) {
|
} else if (memcmp(config, "path.hash.mode", 14) == 0) {
|
||||||
sprintf(reply, "> %d", (uint32_t)_prefs->path_hash_mode);
|
sprintf(reply, "> %d", (uint32_t)_prefs->path_hash_mode);
|
||||||
|
} else if (memcmp(config, "loop.detect", 11) == 0) {
|
||||||
|
if (_prefs->loop_detect == LOOP_DETECT_OFF) {
|
||||||
|
strcpy(reply, "> off");
|
||||||
|
} else if (_prefs->loop_detect == LOOP_DETECT_MINIMAL) {
|
||||||
|
strcpy(reply, "> minimal");
|
||||||
|
} else if (_prefs->loop_detect == LOOP_DETECT_MODERATE) {
|
||||||
|
strcpy(reply, "> moderate");
|
||||||
|
} else {
|
||||||
|
strcpy(reply, "> strict");
|
||||||
|
}
|
||||||
} else if (memcmp(config, "tx", 2) == 0 && (config[2] == 0 || config[2] == ' ')) {
|
} else if (memcmp(config, "tx", 2) == 0 && (config[2] == 0 || config[2] == ' ')) {
|
||||||
sprintf(reply, "> %d", (int32_t) _prefs->tx_power_dbm);
|
sprintf(reply, "> %d", (int32_t) _prefs->tx_power_dbm);
|
||||||
} else if (memcmp(config, "freq", 4) == 0) {
|
} else if (memcmp(config, "freq", 4) == 0) {
|
||||||
@@ -575,6 +587,26 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
|||||||
} else {
|
} else {
|
||||||
strcpy(reply, "Error, must be 0,1, or 2");
|
strcpy(reply, "Error, must be 0,1, or 2");
|
||||||
}
|
}
|
||||||
|
} else if (memcmp(config, "loop.detect ", 12) == 0) {
|
||||||
|
config += 12;
|
||||||
|
uint8_t mode;
|
||||||
|
if (memcmp(config, "off", 3) == 0) {
|
||||||
|
mode = LOOP_DETECT_OFF;
|
||||||
|
} else if (memcmp(config, "minimal", 7) == 0) {
|
||||||
|
mode = LOOP_DETECT_MINIMAL;
|
||||||
|
} else if (memcmp(config, "moderate", 8) == 0) {
|
||||||
|
mode = LOOP_DETECT_MODERATE;
|
||||||
|
} else if (memcmp(config, "strict", 6) == 0) {
|
||||||
|
mode = LOOP_DETECT_STRICT;
|
||||||
|
} else {
|
||||||
|
mode = 0xFF;
|
||||||
|
strcpy(reply, "Error, must be: off, minimal, moderate, or strict");
|
||||||
|
}
|
||||||
|
if (mode != 0xFF) {
|
||||||
|
_prefs->loop_detect = mode;
|
||||||
|
savePrefs();
|
||||||
|
strcpy(reply, "OK");
|
||||||
|
}
|
||||||
} else if (memcmp(config, "tx ", 3) == 0) {
|
} else if (memcmp(config, "tx ", 3) == 0) {
|
||||||
_prefs->tx_power_dbm = atoi(&config[3]);
|
_prefs->tx_power_dbm = atoi(&config[3]);
|
||||||
savePrefs();
|
savePrefs();
|
||||||
|
|||||||
@@ -13,6 +13,11 @@
|
|||||||
#define ADVERT_LOC_SHARE 1
|
#define ADVERT_LOC_SHARE 1
|
||||||
#define ADVERT_LOC_PREFS 2
|
#define ADVERT_LOC_PREFS 2
|
||||||
|
|
||||||
|
#define LOOP_DETECT_OFF 0
|
||||||
|
#define LOOP_DETECT_MINIMAL 1
|
||||||
|
#define LOOP_DETECT_MODERATE 2
|
||||||
|
#define LOOP_DETECT_STRICT 3
|
||||||
|
|
||||||
struct NodePrefs { // persisted to file
|
struct NodePrefs { // persisted to file
|
||||||
float airtime_factor;
|
float airtime_factor;
|
||||||
char node_name[32];
|
char node_name[32];
|
||||||
@@ -53,6 +58,7 @@ struct NodePrefs { // persisted to file
|
|||||||
float adc_multiplier;
|
float adc_multiplier;
|
||||||
char owner_info[120];
|
char owner_info[120];
|
||||||
uint8_t path_hash_mode; // which path mode to use when sending
|
uint8_t path_hash_mode; // which path mode to use when sending
|
||||||
|
uint8_t loop_detect;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CommonCLICallbacks {
|
class CommonCLICallbacks {
|
||||||
|
|||||||
Reference in New Issue
Block a user