Add some lora parameter clamping logic to coalesce to defaults and enforce some bounds (#9808)
This commit is contained in:
+18
-5
@@ -66,9 +66,22 @@ class Default
|
|||||||
if (numOnlineNodes <= 40) {
|
if (numOnlineNodes <= 40) {
|
||||||
return 1.0;
|
return 1.0;
|
||||||
} else {
|
} else {
|
||||||
// Get bandwidth in kHz - convert from code if not using preset
|
// Resolve SF and BW from preset or manual config
|
||||||
float bwKHz =
|
// When use_preset is true, config.lora.spread_factor and bandwidth may be 0
|
||||||
config.lora.use_preset ? modemPresetToBwKHz(config.lora.modem_preset, false) : bwCodeToKHz(config.lora.bandwidth);
|
// because applyModemConfig() sets them on RadioInterface, not on config.lora
|
||||||
|
float bwKHz;
|
||||||
|
uint8_t sf;
|
||||||
|
uint8_t cr;
|
||||||
|
if (config.lora.use_preset) {
|
||||||
|
modemPresetToParams(config.lora.modem_preset, false, bwKHz, sf, cr);
|
||||||
|
} else {
|
||||||
|
sf = config.lora.spread_factor;
|
||||||
|
bwKHz = bwCodeToKHz(config.lora.bandwidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guard against invalid values
|
||||||
|
sf = clampSpreadFactor(sf);
|
||||||
|
bwKHz = clampBandwidthKHz(bwKHz);
|
||||||
|
|
||||||
// throttlingFactor = 2^SF / (BW_in_kHz * scaling_divisor)
|
// throttlingFactor = 2^SF / (BW_in_kHz * scaling_divisor)
|
||||||
// With scaling_divisor=100:
|
// With scaling_divisor=100:
|
||||||
@@ -76,11 +89,11 @@ class Default
|
|||||||
// In SF10 and BW=250khz (mediumslow), this gives 0.04096 rather than the original 0.04
|
// In SF10 and BW=250khz (mediumslow), this gives 0.04096 rather than the original 0.04
|
||||||
// In SF9 and BW=250khz (mediumfast), this gives 0.02048 rather than the original 0.02
|
// In SF9 and BW=250khz (mediumfast), this gives 0.02048 rather than the original 0.02
|
||||||
// In SF7 and BW=250khz (shortfast), this gives 0.00512 rather than the original 0.01
|
// In SF7 and BW=250khz (shortfast), this gives 0.00512 rather than the original 0.01
|
||||||
float throttlingFactor = static_cast<float>(pow_of_2(config.lora.spread_factor)) / (bwKHz * 100.0f);
|
float throttlingFactor = static_cast<float>(pow_of_2(sf)) / (bwKHz * 100.0f);
|
||||||
|
|
||||||
#if USERPREFS_EVENT_MODE
|
#if USERPREFS_EVENT_MODE
|
||||||
// If we are in event mode, scale down the throttling factor by 4
|
// If we are in event mode, scale down the throttling factor by 4
|
||||||
throttlingFactor = static_cast<float>(pow_of_2(config.lora.spread_factor)) / (bwKHz * 25.0f);
|
throttlingFactor = static_cast<float>(pow_of_2(sf)) / (bwKHz * 25.0f);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Scaling up traffic based on number of nodes over 40
|
// Scaling up traffic based on number of nodes over 40
|
||||||
|
|||||||
@@ -24,6 +24,45 @@ extern const RegionInfo *myRegion;
|
|||||||
|
|
||||||
extern void initRegion();
|
extern void initRegion();
|
||||||
|
|
||||||
|
// Valid LoRa spread factor range and defaults
|
||||||
|
constexpr uint8_t LORA_SF_MIN = 7;
|
||||||
|
constexpr uint8_t LORA_SF_MAX = 12;
|
||||||
|
constexpr uint8_t LORA_SF_DEFAULT = 11; // LONG_FAST default
|
||||||
|
|
||||||
|
// Valid LoRa coding rate range and default
|
||||||
|
constexpr uint8_t LORA_CR_MIN = 4;
|
||||||
|
constexpr uint8_t LORA_CR_MAX = 8;
|
||||||
|
constexpr uint8_t LORA_CR_DEFAULT = 5; // LONG_FAST default
|
||||||
|
|
||||||
|
// Default bandwidth in kHz (LONG_FAST)
|
||||||
|
constexpr float LORA_BW_DEFAULT_KHZ = 250.0f;
|
||||||
|
|
||||||
|
/// Clamp spread factor to the valid LoRa range [7, 12].
|
||||||
|
/// Out-of-range values (including 0 from unset preset mode) return LORA_SF_DEFAULT.
|
||||||
|
static inline uint8_t clampSpreadFactor(uint8_t sf)
|
||||||
|
{
|
||||||
|
if (sf < LORA_SF_MIN || sf > LORA_SF_MAX)
|
||||||
|
return LORA_SF_DEFAULT;
|
||||||
|
return sf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clamp coding rate to the valid LoRa range [4, 8].
|
||||||
|
/// Out-of-range values return LORA_CR_DEFAULT.
|
||||||
|
static inline uint8_t clampCodingRate(uint8_t cr)
|
||||||
|
{
|
||||||
|
if (cr < LORA_CR_MIN || cr > LORA_CR_MAX)
|
||||||
|
return LORA_CR_DEFAULT;
|
||||||
|
return cr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ensure bandwidth is positive. Non-positive values return LORA_BW_DEFAULT_KHZ.
|
||||||
|
static inline float clampBandwidthKHz(float bwKHz)
|
||||||
|
{
|
||||||
|
if (bwKHz <= 0.0f)
|
||||||
|
return LORA_BW_DEFAULT_KHZ;
|
||||||
|
return bwKHz;
|
||||||
|
}
|
||||||
|
|
||||||
static inline float bwCodeToKHz(uint16_t bwCode)
|
static inline float bwCodeToKHz(uint16_t bwCode)
|
||||||
{
|
{
|
||||||
if (bwCode == 31)
|
if (bwCode == 31)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Default.h"
|
#include "Default.h"
|
||||||
|
#include "MeshRadio.h"
|
||||||
#include "TypeConversions.h"
|
#include "TypeConversions.h"
|
||||||
|
|
||||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||||
@@ -756,20 +757,14 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
|
|||||||
LOG_INFO("Set config: LoRa");
|
LOG_INFO("Set config: LoRa");
|
||||||
config.has_lora = true;
|
config.has_lora = true;
|
||||||
|
|
||||||
if (validatedLora.coding_rate < 4 || validatedLora.coding_rate > 8) {
|
if (validatedLora.coding_rate != clampCodingRate(validatedLora.coding_rate)) {
|
||||||
LOG_WARN("Invalid coding_rate %d, setting to 5", validatedLora.coding_rate);
|
LOG_WARN("Invalid coding_rate %d, setting to %d", validatedLora.coding_rate, LORA_CR_DEFAULT);
|
||||||
validatedLora.coding_rate = 5;
|
validatedLora.coding_rate = LORA_CR_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (validatedLora.spread_factor < 7 || validatedLora.spread_factor > 12) {
|
if (validatedLora.spread_factor != clampSpreadFactor(validatedLora.spread_factor)) {
|
||||||
LOG_WARN("Invalid spread_factor %d, setting to 11", validatedLora.spread_factor);
|
LOG_WARN("Invalid spread_factor %d, setting to %d", validatedLora.spread_factor, LORA_SF_DEFAULT);
|
||||||
validatedLora.spread_factor = 11;
|
validatedLora.spread_factor = LORA_SF_DEFAULT;
|
||||||
}
|
|
||||||
|
|
||||||
if (validatedLora.bandwidth == 0) {
|
|
||||||
int originalBandwidth = validatedLora.bandwidth;
|
|
||||||
validatedLora.bandwidth = myRegion->wideLora ? 800 : 250;
|
|
||||||
LOG_WARN("Invalid bandwidth %d, setting to default", originalBandwidth);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no lora radio parameters change, don't need to reboot
|
// If no lora radio parameters change, don't need to reboot
|
||||||
|
|||||||
Reference in New Issue
Block a user