1.14 changes merge

This commit is contained in:
liquidraver
2026-03-06 07:56:17 +01:00
parent 06aed018c3
commit 76b87292c3
5 changed files with 77 additions and 4 deletions
+1 -1
View File
@@ -1856,7 +1856,7 @@ bool CompanionMesh::handleProtocolFrame(const uint8_t *data, size_t len)
#endif
static const uint8_t fw_build[12] = FIRMWARE_BUILD_DATE;
static const uint8_t model[40] = CONFIG_ZEPHCORE_BOARD_NAME;
static const uint8_t version[20] = "v1.13.0-zephyr";
static const uint8_t version[20] = "v1.14.0-zephyr";
uint8_t rsp[82];
rsp[0] = PACKET_DEVICE_INFO;
rsp[1] = 10; // FIRMWARE_VER_CODE - v10 = path_hash_mode support
+31
View File
@@ -396,10 +396,41 @@ mesh::Packet* RepeaterMesh::createSelfAdvert() {
return createAdvert(self_id, app_data, app_data_len);
}
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 RepeaterMesh::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) {
if (self_id.isHashMatch(path, hash_size)) n++;
hash_count--;
path += hash_size;
}
return n >= max_counters[hash_size];
}
bool RepeaterMesh::allowPacketForward(const mesh::Packet* packet) {
if (_prefs.disable_fwd) return false;
if (packet->isRouteFlood() && packet->getPathHashCount() >= _prefs.flood_max) return false;
if (packet->isRouteFlood() && recv_pkt_region == nullptr) 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_MODERATE) {
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;
}
+2 -1
View File
@@ -25,7 +25,7 @@
#include "RepeaterDataStore.h"
#ifndef FIRMWARE_VERSION
#define FIRMWARE_VERSION "v1.13.0-zephyr"
#define FIRMWARE_VERSION "v1.14.0-zephyr"
#endif
#ifndef FIRMWARE_BUILD_DATE
@@ -121,6 +121,7 @@ protected:
}
bool allowPacketForward(const mesh::Packet* packet) override;
bool isLooped(const mesh::Packet* packet, const uint8_t max_counters[]);
const char* getLogDateTime() override;
void logRxRaw(float snr, float rssi, const uint8_t raw[], int len) override;
+37 -2
View File
@@ -90,7 +90,8 @@ void CommonCLI::loadPrefs(const char* path) {
ok = ok && prefs_read(&file, &_prefs->bw, sizeof(_prefs->bw)); // 116
ok = ok && prefs_read(&file, &_prefs->agc_reset_interval, sizeof(_prefs->agc_reset_interval)); // 120
ok = ok && prefs_read(&file, &_prefs->path_hash_mode, sizeof(_prefs->path_hash_mode)); // 121
ok = ok && prefs_read(&file, pad, 2); // 122
ok = ok && prefs_read(&file, &_prefs->loop_detect, sizeof(_prefs->loop_detect)); // 122
ok = ok && prefs_read(&file, pad, 1); // 123
ok = ok && prefs_read(&file, &_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
ok = ok && prefs_read(&file, &_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval)); // 125
ok = ok && prefs_read(&file, &_prefs->interference_threshold, sizeof(_prefs->interference_threshold)); // 126
@@ -186,7 +187,8 @@ void CommonCLI::savePrefs(const char* path) {
fs_write(&file, &_prefs->bw, sizeof(_prefs->bw));
fs_write(&file, &_prefs->agc_reset_interval, sizeof(_prefs->agc_reset_interval));
fs_write(&file, &_prefs->path_hash_mode, sizeof(_prefs->path_hash_mode));
fs_write(&file, pad, 2);
fs_write(&file, &_prefs->loop_detect, sizeof(_prefs->loop_detect));
fs_write(&file, pad, 1);
fs_write(&file, &_prefs->flood_max, sizeof(_prefs->flood_max));
fs_write(&file, &_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval));
fs_write(&file, &_prefs->interference_threshold, sizeof(_prefs->interference_threshold));
@@ -302,6 +304,9 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
} else if (memcmp(command, "clkreboot", 9) == 0) {
getRTCClock()->setCurrentTime(1715770351); // 15 May 2024, 8:50pm
_board->reboot();
} else if (memcmp(command, "advert.zerohop", 14) == 0) {
_callbacks->sendSelfAdvertisement(1500, false); // 0-hop (direct) advert
strcpy(reply, "OK - zerohop advert sent");
} else if (memcmp(command, "advert", 6) == 0) {
_callbacks->sendSelfAdvertisement(1500, true);
strcpy(reply, "OK - Advert sent");
@@ -430,6 +435,16 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
*reply = 0;
} else if (memcmp(config, "path.hash.mode", 14) == 0) {
snprintf(reply, CLI_REPLY_SIZE, "> %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] == ' ')) {
snprintf(reply, CLI_REPLY_SIZE, "> %d", (int)_prefs->tx_power_dbm);
} else if (memcmp(config, "freq", 4) == 0) {
@@ -618,6 +633,26 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
} else {
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) {
int val = atoi(&config[3]);
#ifdef CONFIG_ZEPHCORE_MAX_TX_POWER_DBM
+6
View File
@@ -23,6 +23,11 @@
#define ADVERT_LOC_SHARE 1
#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 {
/* ---- Common fields (both roles) ---- */
float airtime_factor;
@@ -70,6 +75,7 @@ struct NodePrefs {
uint8_t client_repeat; // 1 = offgrid mode (forward packets), 0 = companion only
uint8_t path_hash_mode; // which path mode to use when sending (0-2)
uint8_t autoadd_max_hops; // 0 = no limit, 1 = direct (0 hops), N = up to N-1 hops (max 64)
uint8_t loop_detect; // LOOP_DETECT_OFF/MINIMAL/MODERATE/STRICT
};
/* Default prefs — MUST match LoRaConfig.h defaults for radio interop.