#ifndef SUBGHZ_SCANNER_H
#define SUBGHZ_SCANNER_H

// ============================================================================
// subghz_scanner.h — Sub-GHz long-range RC control-link burst detector
// (ADDITIVE, off by default until enabled).
//
// SCOPE, STATED HONESTLY: long-range FPV/drone control links (ExpressLRS/
// ELRS, TBS Crossfire) increasingly run on 433/868/915 MHz specifically
// because 2.4 GHz has short range -- a sensor watching only 2.4 GHz is
// blind to exactly the drones flown far enough away to need this. This
// module does NOT attempt full protocol decode (that needs each
// protocol's exact modulation/sync-word/whitening spec, a much larger
// reverse-engineering effort than tonight's scope). It's an energy/burst-
// timing detector: brief RSSI-polling dwells on candidate sub-GHz
// frequencies, counting threshold-crossings to see if the burst rate
// falls in the range these control links actually use (50/150/250/500 Hz
// packet rates), which a continuous carrier or random noise would not
// produce.
//
// VALIDATION CAVEAT: no real ELRS or Crossfire transmitter was available
// to generate ground-truth over-the-air signals during development --
// unlike the WiFi/BLE handset work, which had real ambient devices to
// test against. This has been verified to compile correctly, run without
// disrupting the LoRa mesh (the critical regression risk, since this
// shares the sensor's one physical SX1262 radio with mesh_publish.cpp),
// and produce plausible-shaped output -- it has NOT been verified against
// an actual over-the-air control-link signal. Treat detections as a
// heuristic lead worth investigating, not a confirmed identification.
//
// UPDATE (2026-07-30): the plausibility BAND itself (not the live SX1262
// RSSI-dwell/threshold-crossing code, which still needs a real transmitter
// to validate) was cross-checked against real, sourced reference data --
// ExpressLRS's own published rate list and TBS Crossfire's real measured
// 150 Hz rate from third-party RF reverse-engineering (g3gg0.de) -- and
// found genuinely miscalibrated: the old 600 Hz ceiling would have
// rejected a real ELRS link running at its documented 1000 Hz 900MHz FSK
// rate as implausible. Widened to 1200 Hz; see subghz_scanner.cpp for the
// sourcing detail. This closes the gap between "the band matches real
// protocol specs" and "the band was checked at all" -- it does NOT close
// the live-hardware gap above (dwell timing, SPI polling rate at 1000 Hz,
// SNR against real background RF all still unverified without a real
// transmitter).
//
// Radio-sharing discipline: this uses the SAME SX1262 the LoRa mesh relies
// on (mesh_publish.cpp owns it). Dwells are brief (a few hundred ms) and
// infrequent (default: every 60s), and ALWAYS restore the mesh's 915 MHz
// frequency + call mesh_start_receive() afterward, matching the existing
// TSCM_SWEEP command's discipline -- never leaves the radio parked
// off-mesh-frequency.
// ============================================================================

#include <cstdint>
#include <cstddef>

// Pure plausibility check: does this dwell's threshold-crossing rate fall
// in the real control-link packet-rate band (20-1200 Hz, generous margin
// around real sourced rates: TBS Crossfire measured at a real, captured
// 150 Hz / 6.666ms via third-party reverse engineering (g3gg0.de), and
// ExpressLRS's own docs list 900MHz-band rates of 25/50/100/200/250/1000 Hz
// FSK — expresslrs.org/info/signal-health/). No radio access -- safe to
// unit test directly without a real SX1262.
bool subghz_is_plausible_rate(float rate_hz);

void subghz_scanner_init();

// Call periodically from the main loop -- internally no-ops unless the
// scan interval has elapsed. Runs one brief scan cycle (all candidate
// frequencies) when it does fire, then restores mesh RX.
void subghz_scanner_tick();

struct SubGhzFinding {
    float    freq_mhz;
    float    estimated_rate_hz;   // burst rate observed during the dwell
    int16_t  peak_rssi_dbm;
};

struct SubGhzScannerStats {
    uint32_t scan_cycles_completed;
    uint16_t findings_last_cycle;   // frequencies with a plausible burst pattern
};

void subghz_scanner_get_stats(SubGhzScannerStats* out);

// Snapshot findings from the most recent completed scan cycle. Returns
// the number of entries written (<= max).
size_t subghz_scanner_list_findings(SubGhzFinding* out, size_t max);

#endif // SUBGHZ_SCANNER_H
