mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-10-23 21:33:53 +00:00
Share radio profile validation and simplify bounded airtime arithmetic
This commit is contained in:
1 parent
44ba5b4f18
commit
1fd993ecf5
2 files changed
+18
-19
No files matched your search
+10
-7
@@ -146,15 +146,18 @@ class RadioProfiles {
|
||||
const RadioProfileParams& params(uint8_t profile) const {
|
||||
return profile == 1 ? secondary.params : primary;
|
||||
}
|
||||
static bool valid(const RadioProfileParams& p) {
|
||||
if (!isfinite(p.freq) || !isfinite(p.bw) || p.freq < 137 || p.freq > 2500
|
||||
static bool valid(const RadioProfileParams& p, bool extended_bandwidths = true) {
|
||||
if (!(p.freq >= 137 && p.freq <= 2500)
|
||||
|| p.sf < 5 || p.sf > 12 || p.cr < 5 || p.cr > 8
|
||||
|| (p.protocol != RadioProfileProtocol::MeshCore && p.protocol != RadioProfileProtocol::Meshtext
|
||||
&& p.protocol != RadioProfileProtocol::Ethernet)
|
||||
|| (p.preamble != 0 && (p.preamble < 8 || p.preamble > MaxPreamble))) return false;
|
||||
static constexpr float bandwidths[] = {7.8f, 10.4f, 15.6f, 20.8f, 31.25f, 41.67f, 41.7f,
|
||||
62.5f, 83.34f, 101.56f, 125, 203.125f, 250, 406.25f, 500, 812.5f, 1000, 1625};
|
||||
for (float bw : bandwidths) if (fabsf(p.bw - bw) < 0.01f) return true;
|
||||
// The first ten entries are the shared SX126x/SX127x bandwidth subset.
|
||||
static constexpr float bandwidths[] = {7.8f, 10.4f, 15.6f, 20.8f, 31.25f, 41.7f,
|
||||
62.5f, 125, 250, 500, 41.67f, 83.34f, 101.56f, 203.125f,
|
||||
406.25f, 812.5f, 1000, 1625};
|
||||
const size_t count = extended_bandwidths ? sizeof(bandwidths) / sizeof(bandwidths[0]) : 10;
|
||||
for (size_t i = 0; i < count; ++i) if (fabsf(p.bw - bandwidths[i]) < 0.01f) return true;
|
||||
return false;
|
||||
}
|
||||
static double symbolUs(const RadioProfileParams& p) {
|
||||
@@ -168,13 +171,13 @@ class RadioProfiles {
|
||||
const double symbol = symbolUs(p);
|
||||
if (symbol <= 0) return false;
|
||||
const int de = symbol >= 16000 ? 1 : 0;
|
||||
const int denominator = 4 * (p.sf - 2 * de);
|
||||
const int denominator = p.sf - 2 * de;
|
||||
// The payload expression is integral apart from this small rational
|
||||
// ceiling. Preserve even invalid-SF behavior: a zero denominator was
|
||||
// infinite (and failed the limit), while signed division rounds a
|
||||
// negative quotient toward zero, exactly its mathematical ceiling.
|
||||
if (!denominator) return false;
|
||||
const int numerator = 8 * 255 - 4 * p.sf + (p.sf <= 6 ? 20 : 28) + 16;
|
||||
const int numerator = 2 * 255 - p.sf + (p.sf <= 6 ? 9 : 11);
|
||||
const double payload = 8 + (denominator > 0
|
||||
? (numerator + denominator - 1) / denominator : numerator / denominator) * 8;
|
||||
// RadioLib's microsecond airtime calculation multiplies by four before
|
||||
|
||||
@@ -491,19 +491,17 @@ mesh::RadioParamApplyResult RadioLibWrapper::trySetParams(float freq, float bw,
|
||||
}
|
||||
|
||||
bool RadioLibWrapper::validateProfile(const mesh::RadioProfileParams& p) const {
|
||||
#if MESH_RADIO_PROFILE_CHIP != 1110 && MESH_RADIO_PROFILE_CHIP != 1121 && MESH_RADIO_PROFILE_CHIP != 2021 && MESH_RADIO_PROFILE_CHIP != 68 && MESH_RADIO_PROFILE_CHIP != 1272
|
||||
if (!mesh::RadioProfiles::valid(p, false)) return false;
|
||||
#else
|
||||
if (!mesh::RadioProfiles::valid(p)) return false;
|
||||
#endif
|
||||
if (p.protocol == mesh::RadioProfileProtocol::Meshtext && !supportsMeshtext()) return false;
|
||||
#if MESH_ENABLE_ETHERNET_WIRE
|
||||
if (p.protocol == mesh::RadioProfileProtocol::Ethernet && !supportsEthernetTunnel()) return false;
|
||||
#else
|
||||
if (p.protocol == mesh::RadioProfileProtocol::Ethernet) return false;
|
||||
#endif
|
||||
#if MESH_RADIO_PROFILE_CHIP != 1110 && MESH_RADIO_PROFILE_CHIP != 1121 && MESH_RADIO_PROFILE_CHIP != 2021 && MESH_RADIO_PROFILE_CHIP != 68 && MESH_RADIO_PROFILE_CHIP != 1272
|
||||
static constexpr float bandwidths[] = {7.8f, 10.4f, 15.6f, 20.8f, 31.25f, 41.7f, 62.5f, 125, 250, 500};
|
||||
bool supported = false;
|
||||
for (float bw : bandwidths) if (fabsf(p.bw - bw) < 0.01f) supported = true;
|
||||
if (!supported) return false;
|
||||
#endif
|
||||
#if MESH_RADIO_PROFILE_CHIP == 1276
|
||||
return p.freq >= 137 && p.freq <= 1020 && p.sf >= 7 && p.bw <= 500;
|
||||
#elif MESH_RADIO_PROFILE_CHIP == 1272
|
||||
@@ -675,9 +673,8 @@ uint32_t RadioLibWrapper::getBeaconAirtime(const mesh::RadioProfileParams& p, in
|
||||
#endif
|
||||
? 1 : 0;
|
||||
// Round the small integer bit/block ratio without floating-point division.
|
||||
const int numerator = 8 * length - 4 * p.sf + (p.sf <= 6 ? 20 : 28) + 16;
|
||||
const int denominator = 4 * (p.sf - 2 * de);
|
||||
const int coded = numerator > 0 ? (numerator + denominator - 1) / denominator : 0;
|
||||
const int denominator = p.sf - 2 * de;
|
||||
const int coded = (2 * length + (p.sf <= 6 ? 8 : 10) - 2 * de) / denominator;
|
||||
const double payload = 8 + coded * p.cr;
|
||||
return static_cast<uint32_t>(ceil((preamble + (p.sf <= 6 ? 6.25 : 4.25) + payload)
|
||||
* symbol / 1000.0));
|
||||
@@ -1016,9 +1013,8 @@ uint32_t RadioLibWrapper::getProfileAirtime(uint8_t profile, int len, uint8_t cr
|
||||
#endif
|
||||
? 1 : 0;
|
||||
// Round the small integer bit/block ratio without floating-point division.
|
||||
const int numerator = 8 * len - 4 * p.sf + (p.sf <= 6 ? 20 : 28) + 16;
|
||||
const int denominator = 4 * (p.sf - 2 * de);
|
||||
const int coded = numerator > 0 ? (numerator + denominator - 1) / denominator : 0;
|
||||
const int denominator = p.sf - 2 * de;
|
||||
const int coded = (2 * len + (p.sf <= 6 ? 8 : 10) - 2 * de) / denominator;
|
||||
const double payload_symbols = 8 + coded * cr;
|
||||
const double suffix = p.sf <= 6 ? 6.25 : 4.25;
|
||||
const double airtime = ceil((profilePreamble(profile) + suffix + payload_symbols) * symbol / 1000.0);
|
||||
|
||||
Reference in new issue
Block a user