qac-cli-commands #26
|
|
@ -396,15 +396,23 @@ class Streamer:
|
||||||
try:
|
try:
|
||||||
sdr, device_key = self._registry.acquire(device, identifier)
|
sdr, device_key = self._registry.acquire(device, identifier)
|
||||||
_apply_sdr_config(sdr, radio_config)
|
_apply_sdr_config(sdr, radio_config)
|
||||||
# Only call init_tx when the hub supplied the three required
|
# init_tx is mandatory for any driver that exposes it: drivers
|
||||||
# parameters. Drivers that gate _stream_tx on _tx_initialized
|
# that gate _stream_tx on _tx_initialized (Pluto, HackRF, USRP,
|
||||||
# (e.g. Pluto) need this; drivers that don't (e.g. Mock) tolerate
|
# …) crash with a confusing "TX was not initialized" error 2 s
|
||||||
# its absence.
|
# later in the executor thread if we skip it. Treat the three
|
||||||
|
# required keys as a hard contract — a missing one is a hub-side
|
||||||
|
# manifest bug and we want it surfaced immediately, not papered
|
||||||
|
# over with stale radio state.
|
||||||
|
if hasattr(sdr, "init_tx"):
|
||||||
init_args = {
|
init_args = {
|
||||||
k: radio_config.get(f"tx_{k}")
|
k: radio_config.get(f"tx_{k}")
|
||||||
for k in ("sample_rate", "center_frequency", "gain")
|
for k in ("sample_rate", "center_frequency", "gain")
|
||||||
}
|
}
|
||||||
if hasattr(sdr, "init_tx") and all(v is not None for v in init_args.values()):
|
missing = [f"tx_{k}" for k, v in init_args.items() if v is None]
|
||||||
|
if missing:
|
||||||
|
raise ValueError(
|
||||||
|
f"tx_start missing required radio_config keys: {missing}"
|
||||||
|
)
|
||||||
sdr.init_tx(
|
sdr.init_tx(
|
||||||
sample_rate=init_args["sample_rate"],
|
sample_rate=init_args["sample_rate"],
|
||||||
center_frequency=init_args["center_frequency"],
|
center_frequency=init_args["center_frequency"],
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ def test_rx_and_tx_share_one_sdr_instance():
|
||||||
"radio_config": {
|
"radio_config": {
|
||||||
"device": "mock",
|
"device": "mock",
|
||||||
"buffer_size": 16,
|
"buffer_size": 16,
|
||||||
|
"tx_sample_rate": 1_000_000,
|
||||||
"tx_gain": -20,
|
"tx_gain": -20,
|
||||||
"tx_center_frequency": 2.45e9,
|
"tx_center_frequency": 2.45e9,
|
||||||
"underrun_policy": "zero",
|
"underrun_policy": "zero",
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,14 @@ def test_tx_stop_releases_sdr():
|
||||||
{
|
{
|
||||||
"type": "tx_start",
|
"type": "tx_start",
|
||||||
"app_id": "a",
|
"app_id": "a",
|
||||||
"radio_config": {"device": "mock", "buffer_size": 8, "underrun_policy": "zero"},
|
"radio_config": {
|
||||||
|
"device": "mock",
|
||||||
|
"buffer_size": 8,
|
||||||
|
"tx_sample_rate": 1_000_000,
|
||||||
|
"tx_center_frequency": 2.45e9,
|
||||||
|
"tx_gain": -20,
|
||||||
|
"underrun_policy": "zero",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
await asyncio.sleep(0.03)
|
await asyncio.sleep(0.03)
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,14 @@ def _last_tx_status(ws):
|
||||||
|
|
||||||
|
|
||||||
def _tx_start(app_id="a", **radio):
|
def _tx_start(app_id="a", **radio):
|
||||||
rc = {"device": "mock", "buffer_size": 16, "underrun_policy": "zero"}
|
rc = {
|
||||||
|
"device": "mock",
|
||||||
|
"buffer_size": 16,
|
||||||
|
"tx_sample_rate": 1_000_000,
|
||||||
|
"tx_center_frequency": 2.45e9,
|
||||||
|
"tx_gain": -20,
|
||||||
|
"underrun_policy": "zero",
|
||||||
|
}
|
||||||
rc.update(radio)
|
rc.update(radio)
|
||||||
return {"type": "tx_start", "app_id": app_id, "radio_config": rc}
|
return {"type": "tx_start", "app_id": app_id, "radio_config": rc}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ def _start_cfg(policy: str, buf: int = 8) -> dict:
|
||||||
"radio_config": {
|
"radio_config": {
|
||||||
"device": "mock",
|
"device": "mock",
|
||||||
"buffer_size": buf,
|
"buffer_size": buf,
|
||||||
|
"tx_sample_rate": 1_000_000,
|
||||||
"tx_gain": -20,
|
"tx_gain": -20,
|
||||||
"tx_center_frequency": 2.45e9,
|
"tx_center_frequency": 2.45e9,
|
||||||
"underrun_policy": policy,
|
"underrun_policy": policy,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user