Files
MrAlders0n 52fc3e1e48 fix(ingest): validate topic keys and harden against malformed input
A short topic pubkey panicked a lane worker and killed the process; keys must
now be 32 bytes and lane workers recover. Also reject non-finite radio values
before airtime, strip NULs from advert names and neighbour scopes, guard the
MQTT client pointer, and never stream a broker copy of a hearing as a repeat.
2026-10-02 16:53:32 -04:00

61 lines
1.7 KiB
Go

// Copyright 2026 Beacon Contributors
// SPDX-License-Identifier: AGPL-3.0-or-later
// Package lora computes LoRa airtime for MeshCore frames, so an observation
// can be costed in milliseconds of channel occupancy.
package lora
import "math"
const (
minSF = 7
maxSF = 12
minCR = 5
maxCR = 8
// MinBWKHz and MaxBWKHz bracket every LoRa bandwidth (7.8 kHz sub-GHz to 1625 kHz SX128x).
MinBWKHz = 7
MaxBWKHz = 1625
)
// PreambleSymbols mirrors MeshCore's preambleLengthForSF: 32 symbols at SF<=8, 16 above.
func PreambleSymbols(sf int) int {
if sf <= 8 {
return 32
}
return 16
}
// FrameLength is the on-air byte count of a MeshCore frame rebuilt from its stored parts.
func FrameLength(transportCodes bool, pathLen, payloadLen int) int {
n := 1 + 1 + pathLen + payloadLen // header byte + path length byte
if transportCodes {
n += 4
}
return n
}
// TimeOnAirMs is the Semtech LoRa time-on-air (RadioLib getTimeOnAir: CRC on, explicit header,
// LDRO auto at t_sym >= 16 ms). ok is false when any parameter is outside the costable range.
func TimeOnAirMs(frameLen, sf int, bwKHz float64, cr int) (ms float64, ok bool) {
if frameLen <= 0 || sf < minSF || sf > maxSF || !(bwKHz >= MinBWKHz && bwKHz <= MaxBWKHz) || cr < minCR || cr > maxCR {
return 0, false
}
tSym := math.Exp2(float64(sf)) / bwKHz
de := 0
if tSym >= 16 {
de = 1
}
n := float64(PreambleSymbols(sf)) + 4.25 + float64(symbols(frameLen, sf, cr, de))
return n * tSym, true
}
// symbols is the Semtech payload symbol count with explicit header and CRC on.
func symbols(frameLen, sf, cr, de int) int {
n := math.Ceil(float64(8*frameLen-4*sf+44)/float64(4*(sf-2*de))) * float64(cr)
if n < 0 {
n = 0
}
return 8 + int(n)
}