From cc75388fd47de9233b3d0f77694a74298682e26f Mon Sep 17 00:00:00 2001 From: James Smith Date: Wed, 8 Jul 2026 19:28:14 +0100 Subject: [PATCH] fix: propagate USRP/BladeRF/HydraSDR through remaining SDR-type lists Several modules independently reimplemented the sdr_type string-to-enum mapping and bandwidth caps instead of using the canonical mapping in utils/sdr/detection.py, so they were never updated when USRP, BladeRF, and HydraSDR support was added: - routes/listening_post/audio.py: the receiver audio-start endpoint hard-rejected these types with a 400, even though the underlying SDRFactory command builder already supports them. - routes/meteor_websocket.py and routes/waterfall_websocket.py: unknown sdr_type strings silently fell back to RTL_SDR, which could build a command against the wrong hardware. Added the missing mapping entries and matching MAX_BANDWIDTH caps for the three new types. - utils/ground_station/iq_bus.py: same silent-fallback mapping gap in IQ capture command building. --- routes/listening_post/audio.py | 2 +- routes/meteor_websocket.py | 6 ++++++ routes/waterfall_websocket.py | 6 ++++++ utils/ground_station/iq_bus.py | 3 +++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/routes/listening_post/audio.py b/routes/listening_post/audio.py index b1567a4..20b165b 100644 --- a/routes/listening_post/audio.py +++ b/routes/listening_post/audio.py @@ -54,7 +54,7 @@ def start_audio() -> Response: if frequency <= 0: return jsonify({"status": "error", "message": "frequency is required"}), 400 - valid_sdr_types = ["rtlsdr", "hackrf", "airspy", "limesdr", "sdrplay"] + valid_sdr_types = ["rtlsdr", "hackrf", "airspy", "limesdr", "sdrplay", "usrp", "bladerf", "hydrasdr"] if sdr_type not in valid_sdr_types: return jsonify({"status": "error", "message": f"Invalid sdr_type. Use: {', '.join(valid_sdr_types)}"}), 400 diff --git a/routes/meteor_websocket.py b/routes/meteor_websocket.py index 72c6fa0..bde89bc 100644 --- a/routes/meteor_websocket.py +++ b/routes/meteor_websocket.py @@ -64,6 +64,9 @@ MAX_BANDWIDTH = { SDRType.LIME_SDR: 20000000, SDRType.AIRSPY: 10000000, SDRType.SDRPLAY: 2000000, + SDRType.USRP: 25000000, + SDRType.BLADE_RF: 40000000, + SDRType.HYDRA_SDR: 10000000, } @@ -87,6 +90,9 @@ def _resolve_sdr_type(sdr_type_str: str) -> SDRType: "limesdr": SDRType.LIME_SDR, "airspy": SDRType.AIRSPY, "sdrplay": SDRType.SDRPLAY, + "usrp": SDRType.USRP, + "bladerf": SDRType.BLADE_RF, + "hydrasdr": SDRType.HYDRA_SDR, } return mapping.get(sdr_type_str.lower(), SDRType.RTL_SDR) diff --git a/routes/waterfall_websocket.py b/routes/waterfall_websocket.py index ca929b5..715b76a 100644 --- a/routes/waterfall_websocket.py +++ b/routes/waterfall_websocket.py @@ -62,6 +62,9 @@ MAX_BANDWIDTH = { SDRType.LIME_SDR: 20000000, SDRType.AIRSPY: 10000000, SDRType.SDRPLAY: 2000000, + SDRType.USRP: 25000000, + SDRType.BLADE_RF: 40000000, + SDRType.HYDRA_SDR: 10000000, } @@ -330,6 +333,9 @@ def _resolve_sdr_type(sdr_type_str: str) -> SDRType: "lime_sdr": SDRType.LIME_SDR, "airspy": SDRType.AIRSPY, "sdrplay": SDRType.SDRPLAY, + "usrp": SDRType.USRP, + "bladerf": SDRType.BLADE_RF, + "hydrasdr": SDRType.HYDRA_SDR, } return mapping.get(sdr_type_str.lower(), SDRType.RTL_SDR) diff --git a/utils/ground_station/iq_bus.py b/utils/ground_station/iq_bus.py index 139e8ad..f1df16c 100644 --- a/utils/ground_station/iq_bus.py +++ b/utils/ground_station/iq_bus.py @@ -281,6 +281,9 @@ class IQBus: "limesdr": SDRType.LIME_SDR, "airspy": SDRType.AIRSPY, "sdrplay": SDRType.SDRPLAY, + "usrp": SDRType.USRP, + "bladerf": SDRType.BLADE_RF, + "hydrasdr": SDRType.HYDRA_SDR, } sdr_type = type_map.get(self._sdr_type.lower(), SDRType.RTL_SDR) builder = SDRFactory.get_builder(sdr_type)