All docsStellar LinkRF bench · by Stellar Systems v0.1.0

API Reference

Radio

Radio runtime (RX/TX FSM) — planned L6

POST/api/v1/radio/frequency

Set frequency#

Request body application/jsonrequired

center_frequency_hzrequired

integer · int64

≥ 0

channel

string

Which side to tune: "rx", "tx" or "both" (default).

RX AND TX ARE INDEPENDENT LOs. Measured on this bench 2026-09-12: the RX LO sat at 2.400 GHz while the TX LO was still at its 2.450 GHz default, so an analyser on TX1A at 2.4 GHz saw nothing and the API reported one "center_frequency_hz" that described neither.

tune_lo

boolean

true (default) also drives the AD9361's analogue LO. false writes only the PL's digital NCO (chan_cfg::FREQ_HZ).

The distinction is not pedantry: until today this route wrote ONLY the NCO, so /radio/status reported a centre frequency the transmitter had never been told about.

Responses

200OKapplication/json
rx_staterequired

string

tx_staterequired

string

center_frequency_hzrequired

integer · int64

≥ 0

rx_gain_dbrequired

integer · int32

tx_gain_dbrequired

integer · int32

loopbackrequired

boolean

timing_lockrequired

boolean

carrier_lockrequired

boolean

rx_lo_hz

integer · int64 · nullable

≥ 0

rx_nco_offset_hzrequired

integer · int64

The DDC's digital offset from the RX LO, signed, in Hz.

tx_nco_offset_hzrequired

integer · int64

The DUC's digital offset from the TX LO, signed, in Hz.

profile_center_frequency_hzrequired

integer · int64

What the applied PROFILE declares as its centre, read from the inert chan_cfg shadow. It describes the configuration, not the radio, and the two diverge the moment anyone tunes by hand.

≥ 0

tx_lo_hz

integer · int64 · nullable

≥ 0

rx_rf_gain_db

number · double · nullable

The part's own gain, in dB at the connector. TX is an ATTENUATION.

tx_rf_gain_db

number · double · nullable

rx_bandwidth_hz

integer · int64 · nullable

The part's ANALOG filter width, per direction, read from IIO.

NOT a PL register — the AD9361 has none in this address space, which is exactly why the datapath diagram could not show it. None means the attribute could not be read, never a default: this is the value that sat at 18 MHz for a 53 kHz signal (STE-998), and a plausible-looking number here would be worse than an absence.

The part QUANTISES what is written, so this read-back legitimately differs from any requested width. It is the truth; the request is not.

SERIALISED EVEN WHEN NULL, unlike its neighbours above, and the difference is deliberate. An ABSENT field cannot be told apart from an older daemon that never had it; an explicit null says "this daemon knows about the bandwidth and could not read it". For a field whose whole point is that nobody could see it before, that distinction is the feature.

≥ 0

tx_bandwidth_hz

integer · int64 · nullable

≥ 0

sample_rate_sps

integer · int64 · nullable

The part's sample rate. Also on /radio/rf-state; carried here so that one call answers "how is the front end configured" instead of two that have to be reconciled.

≥ 0

Request

curl -X POST "http://192.168.2.1:8080/api/v1/radio/frequency" \
  -H "Content-Type: application/json" \
  -d '{
  "center_frequency_hz": 0,
  "channel": "string",
  "tune_lo": true
}'

Response

{
  "rx_state": "string",
  "tx_state": "string",
  "center_frequency_hz": 0,
  "rx_gain_db": 0,
  "tx_gain_db": 0,
  "loopback": true,
  "timing_lock": true,
  "carrier_lock": true,
  "rx_lo_hz": 0,
  "rx_nco_offset_hz": 0,
  "tx_nco_offset_hz": 0,
  "profile_center_frequency_hz": 0,
  "tx_lo_hz": 0,
  "rx_rf_gain_db": 0.0,
  "tx_rf_gain_db": 0.0,
  "rx_bandwidth_hz": 0,
  "tx_bandwidth_hz": 0,
  "sample_rate_sps": 0
}
POST/api/v1/radio/gain

Set gain#

Request body application/jsonrequired

rx_gain_db

integer · int32 · nullable

tx_gain_db

integer · int32 · nullable

Responses

200OKapplication/json
rx_staterequired

string

tx_staterequired

string

center_frequency_hzrequired

integer · int64

≥ 0

rx_gain_dbrequired

integer · int32

tx_gain_dbrequired

integer · int32

loopbackrequired

boolean

timing_lockrequired

boolean

carrier_lockrequired

boolean

rx_lo_hz

integer · int64 · nullable

≥ 0

rx_nco_offset_hzrequired

integer · int64

The DDC's digital offset from the RX LO, signed, in Hz.

tx_nco_offset_hzrequired

integer · int64

The DUC's digital offset from the TX LO, signed, in Hz.

profile_center_frequency_hzrequired

integer · int64

What the applied PROFILE declares as its centre, read from the inert chan_cfg shadow. It describes the configuration, not the radio, and the two diverge the moment anyone tunes by hand.

≥ 0

tx_lo_hz

integer · int64 · nullable

≥ 0

rx_rf_gain_db

number · double · nullable

The part's own gain, in dB at the connector. TX is an ATTENUATION.

tx_rf_gain_db

number · double · nullable

rx_bandwidth_hz

integer · int64 · nullable

The part's ANALOG filter width, per direction, read from IIO.

NOT a PL register — the AD9361 has none in this address space, which is exactly why the datapath diagram could not show it. None means the attribute could not be read, never a default: this is the value that sat at 18 MHz for a 53 kHz signal (STE-998), and a plausible-looking number here would be worse than an absence.

The part QUANTISES what is written, so this read-back legitimately differs from any requested width. It is the truth; the request is not.

SERIALISED EVEN WHEN NULL, unlike its neighbours above, and the difference is deliberate. An ABSENT field cannot be told apart from an older daemon that never had it; an explicit null says "this daemon knows about the bandwidth and could not read it". For a field whose whole point is that nobody could see it before, that distinction is the feature.

≥ 0

tx_bandwidth_hz

integer · int64 · nullable

≥ 0

sample_rate_sps

integer · int64 · nullable

The part's sample rate. Also on /radio/rf-state; carried here so that one call answers "how is the front end configured" instead of two that have to be reconciled.

≥ 0

Request

curl -X POST "http://192.168.2.1:8080/api/v1/radio/gain" \
  -H "Content-Type: application/json" \
  -d '{
  "rx_gain_db": 0,
  "tx_gain_db": 0,
  "domain": {}
}'

Response

{
  "rx_state": "string",
  "tx_state": "string",
  "center_frequency_hz": 0,
  "rx_gain_db": 0,
  "tx_gain_db": 0,
  "loopback": true,
  "timing_lock": true,
  "carrier_lock": true,
  "rx_lo_hz": 0,
  "rx_nco_offset_hz": 0,
  "tx_nco_offset_hz": 0,
  "profile_center_frequency_hz": 0,
  "tx_lo_hz": 0,
  "rx_rf_gain_db": 0.0,
  "tx_rf_gain_db": 0.0,
  "rx_bandwidth_hz": 0,
  "tx_bandwidth_hz": 0,
  "sample_rate_sps": 0
}
POST/api/v1/radio/loopback

Enable loopback#

Request body application/jsonrequired

enabledrequired

boolean

Responses

200OKapplication/json
rx_staterequired

string

tx_staterequired

string

center_frequency_hzrequired

integer · int64

≥ 0

rx_gain_dbrequired

integer · int32

tx_gain_dbrequired

integer · int32

loopbackrequired

boolean

timing_lockrequired

boolean

carrier_lockrequired

boolean

rx_lo_hz

integer · int64 · nullable

≥ 0

rx_nco_offset_hzrequired

integer · int64

The DDC's digital offset from the RX LO, signed, in Hz.

tx_nco_offset_hzrequired

integer · int64

The DUC's digital offset from the TX LO, signed, in Hz.

profile_center_frequency_hzrequired

integer · int64

What the applied PROFILE declares as its centre, read from the inert chan_cfg shadow. It describes the configuration, not the radio, and the two diverge the moment anyone tunes by hand.

≥ 0

tx_lo_hz

integer · int64 · nullable

≥ 0

rx_rf_gain_db

number · double · nullable

The part's own gain, in dB at the connector. TX is an ATTENUATION.

tx_rf_gain_db

number · double · nullable

rx_bandwidth_hz

integer · int64 · nullable

The part's ANALOG filter width, per direction, read from IIO.

NOT a PL register — the AD9361 has none in this address space, which is exactly why the datapath diagram could not show it. None means the attribute could not be read, never a default: this is the value that sat at 18 MHz for a 53 kHz signal (STE-998), and a plausible-looking number here would be worse than an absence.

The part QUANTISES what is written, so this read-back legitimately differs from any requested width. It is the truth; the request is not.

SERIALISED EVEN WHEN NULL, unlike its neighbours above, and the difference is deliberate. An ABSENT field cannot be told apart from an older daemon that never had it; an explicit null says "this daemon knows about the bandwidth and could not read it". For a field whose whole point is that nobody could see it before, that distinction is the feature.

≥ 0

tx_bandwidth_hz

integer · int64 · nullable

≥ 0

sample_rate_sps

integer · int64 · nullable

The part's sample rate. Also on /radio/rf-state; carried here so that one call answers "how is the front end configured" instead of two that have to be reconciled.

≥ 0

Request

curl -X POST "http://192.168.2.1:8080/api/v1/radio/loopback" \
  -H "Content-Type: application/json" \
  -d '{
  "enabled": true
}'

Response

{
  "rx_state": "string",
  "tx_state": "string",
  "center_frequency_hz": 0,
  "rx_gain_db": 0,
  "tx_gain_db": 0,
  "loopback": true,
  "timing_lock": true,
  "carrier_lock": true,
  "rx_lo_hz": 0,
  "rx_nco_offset_hz": 0,
  "tx_nco_offset_hz": 0,
  "profile_center_frequency_hz": 0,
  "tx_lo_hz": 0,
  "rx_rf_gain_db": 0.0,
  "tx_rf_gain_db": 0.0,
  "rx_bandwidth_hz": 0,
  "tx_bandwidth_hz": 0,
  "sample_rate_sps": 0
}
POST/api/v1/radio/reset

Reset#

Request body application/jsonrequired

scoperequired

string

Responses

200OKapplication/json
rx_staterequired

string

tx_staterequired

string

center_frequency_hzrequired

integer · int64

≥ 0

rx_gain_dbrequired

integer · int32

tx_gain_dbrequired

integer · int32

loopbackrequired

boolean

timing_lockrequired

boolean

carrier_lockrequired

boolean

rx_lo_hz

integer · int64 · nullable

≥ 0

rx_nco_offset_hzrequired

integer · int64

The DDC's digital offset from the RX LO, signed, in Hz.

tx_nco_offset_hzrequired

integer · int64

The DUC's digital offset from the TX LO, signed, in Hz.

profile_center_frequency_hzrequired

integer · int64

What the applied PROFILE declares as its centre, read from the inert chan_cfg shadow. It describes the configuration, not the radio, and the two diverge the moment anyone tunes by hand.

≥ 0

tx_lo_hz

integer · int64 · nullable

≥ 0

rx_rf_gain_db

number · double · nullable

The part's own gain, in dB at the connector. TX is an ATTENUATION.

tx_rf_gain_db

number · double · nullable

rx_bandwidth_hz

integer · int64 · nullable

The part's ANALOG filter width, per direction, read from IIO.

NOT a PL register — the AD9361 has none in this address space, which is exactly why the datapath diagram could not show it. None means the attribute could not be read, never a default: this is the value that sat at 18 MHz for a 53 kHz signal (STE-998), and a plausible-looking number here would be worse than an absence.

The part QUANTISES what is written, so this read-back legitimately differs from any requested width. It is the truth; the request is not.

SERIALISED EVEN WHEN NULL, unlike its neighbours above, and the difference is deliberate. An ABSENT field cannot be told apart from an older daemon that never had it; an explicit null says "this daemon knows about the bandwidth and could not read it". For a field whose whole point is that nobody could see it before, that distinction is the feature.

≥ 0

tx_bandwidth_hz

integer · int64 · nullable

≥ 0

sample_rate_sps

integer · int64 · nullable

The part's sample rate. Also on /radio/rf-state; carried here so that one call answers "how is the front end configured" instead of two that have to be reconciled.

≥ 0

400invalid scopeapplication/json

ApiErrorDRO

Request

curl -X POST "http://192.168.2.1:8080/api/v1/radio/reset" \
  -H "Content-Type: application/json" \
  -d '{
  "scope": "string"
}'

Response

{
  "rx_state": "string",
  "tx_state": "string",
  "center_frequency_hz": 0,
  "rx_gain_db": 0,
  "tx_gain_db": 0,
  "loopback": true,
  "timing_lock": true,
  "carrier_lock": true,
  "rx_lo_hz": 0,
  "rx_nco_offset_hz": 0,
  "tx_nco_offset_hz": 0,
  "profile_center_frequency_hz": 0,
  "tx_lo_hz": 0,
  "rx_rf_gain_db": 0.0,
  "tx_rf_gain_db": 0.0,
  "rx_bandwidth_hz": 0,
  "tx_bandwidth_hz": 0,
  "sample_rate_sps": 0
}
POST/api/v1/radio/rf/calibrate

RF calibrate#

Back to the PL loopback: the AD9361 is bypassed entirely.

Responses

200OKapplication/json

RfStateDRO

Request

curl -X POST "http://192.168.2.1:8080/api/v1/radio/rf/calibrate"

Response

{}
POST/api/v1/radio/rf/kill

RF kill#

EMERGENCY STOP: take RF off the connector, now.

WHAT ACTUALLY REMOVES RF, and what only looks like it. The TX attenuation bottoms out at -89.75 dB and still emits a carrier. An empty DAC still leaks the LO. Closing the modem's egress stops the samples without touching the mixers — measured on this bench, that leaves the LO leakage on the analyser. Only the transceiver's own state machine takes the transmitter down, so ensm_mode = alert is the first thing this does and the one that decides whether the button worked.

The digital steps follow rather than lead: they stop the chain feeding a part that is already off, which matters for what the board is doing when it comes back, not for whether it is emitting.

EVERY STEP IS READ BACK and reported by name. An emergency stop that reports success without checking is worse than no button: it converts "I am not transmitting" from something you verified into something you were told.

It is deliberately NOT a toggle. Coming back is the ordinary conditioning sequence (satlinkctl chain up), which re-establishes the ENSM, the tuning the part lost by leaving FDD, the profile and the path — in that order.

Responses

200OKapplication/json
ensm_moderequired

string

What the part's ENSM reports AFTER the stop. alert is RF off.

stoppedrequired

array of string

Steps that took effect, in the order they were applied.

failedrequired

array of string

Steps that did NOT. Present even when RF is off, because a stop that half-worked and says nothing is the failure mode this exists against.

rf_offrequired

boolean

Is RF actually off at the connector?

recoverrequired

string

How to come back.

Request

curl -X POST "http://192.168.2.1:8080/api/v1/radio/rf/kill"

Response

{
  "ensm_mode": "string",
  "stopped": [
    "string"
  ],
  "failed": [
    "string"
  ],
  "rf_off": true,
  "recover": "string"
}
POST/api/v1/radio/rf/mode/air

RF mode air#

ON AIR. Identical to mode/rf except the part's internal loopback stays

OPEN, so the signal reaches the mixers and the TX port.

The distinction is not cosmetic and it cost an evening: mode/rf closes the AD9361's DIGITAL loopback, which returns TX to RX BEFORE the mixers. In that mode the LOs, the gains and the TX attenuation have no effect whatsoever, so nothing reaches an antenna and none of those settings explains why.

Responses

200OKapplication/json

RfStateDRO

Request

curl -X POST "http://192.168.2.1:8080/api/v1/radio/rf/mode/air"

Response

{}
POST/api/v1/radio/rx{chan}/arm

RX arm#

Path parameters

chanrequired

string

RX channel (1/2)

Responses

202Acceptedapplication/json
rx_staterequired

string

tx_staterequired

string

center_frequency_hzrequired

integer · int64

≥ 0

rx_gain_dbrequired

integer · int32

tx_gain_dbrequired

integer · int32

loopbackrequired

boolean

timing_lockrequired

boolean

carrier_lockrequired

boolean

rx_lo_hz

integer · int64 · nullable

≥ 0

rx_nco_offset_hzrequired

integer · int64

The DDC's digital offset from the RX LO, signed, in Hz.

tx_nco_offset_hzrequired

integer · int64

The DUC's digital offset from the TX LO, signed, in Hz.

profile_center_frequency_hzrequired

integer · int64

What the applied PROFILE declares as its centre, read from the inert chan_cfg shadow. It describes the configuration, not the radio, and the two diverge the moment anyone tunes by hand.

≥ 0

tx_lo_hz

integer · int64 · nullable

≥ 0

rx_rf_gain_db

number · double · nullable

The part's own gain, in dB at the connector. TX is an ATTENUATION.

tx_rf_gain_db

number · double · nullable

rx_bandwidth_hz

integer · int64 · nullable

The part's ANALOG filter width, per direction, read from IIO.

NOT a PL register — the AD9361 has none in this address space, which is exactly why the datapath diagram could not show it. None means the attribute could not be read, never a default: this is the value that sat at 18 MHz for a 53 kHz signal (STE-998), and a plausible-looking number here would be worse than an absence.

The part QUANTISES what is written, so this read-back legitimately differs from any requested width. It is the truth; the request is not.

SERIALISED EVEN WHEN NULL, unlike its neighbours above, and the difference is deliberate. An ABSENT field cannot be told apart from an older daemon that never had it; an explicit null says "this daemon knows about the bandwidth and could not read it". For a field whose whole point is that nobody could see it before, that distinction is the feature.

≥ 0

tx_bandwidth_hz

integer · int64 · nullable

≥ 0

sample_rate_sps

integer · int64 · nullable

The part's sample rate. Also on /radio/rf-state; carried here so that one call answers "how is the front end configured" instead of two that have to be reconciled.

≥ 0

Request

curl -X POST "http://192.168.2.1:8080/api/v1/radio/rx<chan>/arm"

Response

{
  "rx_state": "string",
  "tx_state": "string",
  "center_frequency_hz": 0,
  "rx_gain_db": 0,
  "tx_gain_db": 0,
  "loopback": true,
  "timing_lock": true,
  "carrier_lock": true,
  "rx_lo_hz": 0,
  "rx_nco_offset_hz": 0,
  "tx_nco_offset_hz": 0,
  "profile_center_frequency_hz": 0,
  "tx_lo_hz": 0,
  "rx_rf_gain_db": 0.0,
  "tx_rf_gain_db": 0.0,
  "rx_bandwidth_hz": 0,
  "tx_bandwidth_hz": 0,
  "sample_rate_sps": 0
}
POST/api/v1/radio/rx{chan}/disarm

RX disarm#

Path parameters

chanrequired

string

channel number

Responses

200OKapplication/json
rx_staterequired

string

tx_staterequired

string

center_frequency_hzrequired

integer · int64

≥ 0

rx_gain_dbrequired

integer · int32

tx_gain_dbrequired

integer · int32

loopbackrequired

boolean

timing_lockrequired

boolean

carrier_lockrequired

boolean

rx_lo_hz

integer · int64 · nullable

≥ 0

rx_nco_offset_hzrequired

integer · int64

The DDC's digital offset from the RX LO, signed, in Hz.

tx_nco_offset_hzrequired

integer · int64

The DUC's digital offset from the TX LO, signed, in Hz.

profile_center_frequency_hzrequired

integer · int64

What the applied PROFILE declares as its centre, read from the inert chan_cfg shadow. It describes the configuration, not the radio, and the two diverge the moment anyone tunes by hand.

≥ 0

tx_lo_hz

integer · int64 · nullable

≥ 0

rx_rf_gain_db

number · double · nullable

The part's own gain, in dB at the connector. TX is an ATTENUATION.

tx_rf_gain_db

number · double · nullable

rx_bandwidth_hz

integer · int64 · nullable

The part's ANALOG filter width, per direction, read from IIO.

NOT a PL register — the AD9361 has none in this address space, which is exactly why the datapath diagram could not show it. None means the attribute could not be read, never a default: this is the value that sat at 18 MHz for a 53 kHz signal (STE-998), and a plausible-looking number here would be worse than an absence.

The part QUANTISES what is written, so this read-back legitimately differs from any requested width. It is the truth; the request is not.

SERIALISED EVEN WHEN NULL, unlike its neighbours above, and the difference is deliberate. An ABSENT field cannot be told apart from an older daemon that never had it; an explicit null says "this daemon knows about the bandwidth and could not read it". For a field whose whole point is that nobody could see it before, that distinction is the feature.

≥ 0

tx_bandwidth_hz

integer · int64 · nullable

≥ 0

sample_rate_sps

integer · int64 · nullable

The part's sample rate. Also on /radio/rf-state; carried here so that one call answers "how is the front end configured" instead of two that have to be reconciled.

≥ 0

Request

curl -X POST "http://192.168.2.1:8080/api/v1/radio/rx<chan>/disarm"

Response

{
  "rx_state": "string",
  "tx_state": "string",
  "center_frequency_hz": 0,
  "rx_gain_db": 0,
  "tx_gain_db": 0,
  "loopback": true,
  "timing_lock": true,
  "carrier_lock": true,
  "rx_lo_hz": 0,
  "rx_nco_offset_hz": 0,
  "tx_nco_offset_hz": 0,
  "profile_center_frequency_hz": 0,
  "tx_lo_hz": 0,
  "rx_rf_gain_db": 0.0,
  "tx_rf_gain_db": 0.0,
  "rx_bandwidth_hz": 0,
  "tx_bandwidth_hz": 0,
  "sample_rate_sps": 0
}
GET/api/v1/radio/status

Status#

Responses

200OKapplication/json
rx_staterequired

string

tx_staterequired

string

center_frequency_hzrequired

integer · int64

≥ 0

rx_gain_dbrequired

integer · int32

tx_gain_dbrequired

integer · int32

loopbackrequired

boolean

timing_lockrequired

boolean

carrier_lockrequired

boolean

rx_lo_hz

integer · int64 · nullable

≥ 0

rx_nco_offset_hzrequired

integer · int64

The DDC's digital offset from the RX LO, signed, in Hz.

tx_nco_offset_hzrequired

integer · int64

The DUC's digital offset from the TX LO, signed, in Hz.

profile_center_frequency_hzrequired

integer · int64

What the applied PROFILE declares as its centre, read from the inert chan_cfg shadow. It describes the configuration, not the radio, and the two diverge the moment anyone tunes by hand.

≥ 0

tx_lo_hz

integer · int64 · nullable

≥ 0

rx_rf_gain_db

number · double · nullable

The part's own gain, in dB at the connector. TX is an ATTENUATION.

tx_rf_gain_db

number · double · nullable

rx_bandwidth_hz

integer · int64 · nullable

The part's ANALOG filter width, per direction, read from IIO.

NOT a PL register — the AD9361 has none in this address space, which is exactly why the datapath diagram could not show it. None means the attribute could not be read, never a default: this is the value that sat at 18 MHz for a 53 kHz signal (STE-998), and a plausible-looking number here would be worse than an absence.

The part QUANTISES what is written, so this read-back legitimately differs from any requested width. It is the truth; the request is not.

SERIALISED EVEN WHEN NULL, unlike its neighbours above, and the difference is deliberate. An ABSENT field cannot be told apart from an older daemon that never had it; an explicit null says "this daemon knows about the bandwidth and could not read it". For a field whose whole point is that nobody could see it before, that distinction is the feature.

≥ 0

tx_bandwidth_hz

integer · int64 · nullable

≥ 0

sample_rate_sps

integer · int64 · nullable

The part's sample rate. Also on /radio/rf-state; carried here so that one call answers "how is the front end configured" instead of two that have to be reconciled.

≥ 0

Request

curl "http://192.168.2.1:8080/api/v1/radio/status"

Response

{
  "rx_state": "string",
  "tx_state": "string",
  "center_frequency_hz": 0,
  "rx_gain_db": 0,
  "tx_gain_db": 0,
  "loopback": true,
  "timing_lock": true,
  "carrier_lock": true,
  "rx_lo_hz": 0,
  "rx_nco_offset_hz": 0,
  "tx_nco_offset_hz": 0,
  "profile_center_frequency_hz": 0,
  "tx_lo_hz": 0,
  "rx_rf_gain_db": 0.0,
  "tx_rf_gain_db": 0.0,
  "rx_bandwidth_hz": 0,
  "tx_bandwidth_hz": 0,
  "sample_rate_sps": 0
}
POST/api/v1/radio/tx{chan}/start

TX start#

Path parameters

chanrequired

string

channel number

Responses

202Acceptedapplication/json
rx_staterequired

string

tx_staterequired

string

center_frequency_hzrequired

integer · int64

≥ 0

rx_gain_dbrequired

integer · int32

tx_gain_dbrequired

integer · int32

loopbackrequired

boolean

timing_lockrequired

boolean

carrier_lockrequired

boolean

rx_lo_hz

integer · int64 · nullable

≥ 0

rx_nco_offset_hzrequired

integer · int64

The DDC's digital offset from the RX LO, signed, in Hz.

tx_nco_offset_hzrequired

integer · int64

The DUC's digital offset from the TX LO, signed, in Hz.

profile_center_frequency_hzrequired

integer · int64

What the applied PROFILE declares as its centre, read from the inert chan_cfg shadow. It describes the configuration, not the radio, and the two diverge the moment anyone tunes by hand.

≥ 0

tx_lo_hz

integer · int64 · nullable

≥ 0

rx_rf_gain_db

number · double · nullable

The part's own gain, in dB at the connector. TX is an ATTENUATION.

tx_rf_gain_db

number · double · nullable

rx_bandwidth_hz

integer · int64 · nullable

The part's ANALOG filter width, per direction, read from IIO.

NOT a PL register — the AD9361 has none in this address space, which is exactly why the datapath diagram could not show it. None means the attribute could not be read, never a default: this is the value that sat at 18 MHz for a 53 kHz signal (STE-998), and a plausible-looking number here would be worse than an absence.

The part QUANTISES what is written, so this read-back legitimately differs from any requested width. It is the truth; the request is not.

SERIALISED EVEN WHEN NULL, unlike its neighbours above, and the difference is deliberate. An ABSENT field cannot be told apart from an older daemon that never had it; an explicit null says "this daemon knows about the bandwidth and could not read it". For a field whose whole point is that nobody could see it before, that distinction is the feature.

≥ 0

tx_bandwidth_hz

integer · int64 · nullable

≥ 0

sample_rate_sps

integer · int64 · nullable

The part's sample rate. Also on /radio/rf-state; carried here so that one call answers "how is the front end configured" instead of two that have to be reconciled.

≥ 0

Request

curl -X POST "http://192.168.2.1:8080/api/v1/radio/tx<chan>/start"

Response

{
  "rx_state": "string",
  "tx_state": "string",
  "center_frequency_hz": 0,
  "rx_gain_db": 0,
  "tx_gain_db": 0,
  "loopback": true,
  "timing_lock": true,
  "carrier_lock": true,
  "rx_lo_hz": 0,
  "rx_nco_offset_hz": 0,
  "tx_nco_offset_hz": 0,
  "profile_center_frequency_hz": 0,
  "tx_lo_hz": 0,
  "rx_rf_gain_db": 0.0,
  "tx_rf_gain_db": 0.0,
  "rx_bandwidth_hz": 0,
  "tx_bandwidth_hz": 0,
  "sample_rate_sps": 0
}
POST/api/v1/radio/tx{chan}/stop

TX stop#

Path parameters

chanrequired

string

channel number

Responses

200OKapplication/json
rx_staterequired

string

tx_staterequired

string

center_frequency_hzrequired

integer · int64

≥ 0

rx_gain_dbrequired

integer · int32

tx_gain_dbrequired

integer · int32

loopbackrequired

boolean

timing_lockrequired

boolean

carrier_lockrequired

boolean

rx_lo_hz

integer · int64 · nullable

≥ 0

rx_nco_offset_hzrequired

integer · int64

The DDC's digital offset from the RX LO, signed, in Hz.

tx_nco_offset_hzrequired

integer · int64

The DUC's digital offset from the TX LO, signed, in Hz.

profile_center_frequency_hzrequired

integer · int64

What the applied PROFILE declares as its centre, read from the inert chan_cfg shadow. It describes the configuration, not the radio, and the two diverge the moment anyone tunes by hand.

≥ 0

tx_lo_hz

integer · int64 · nullable

≥ 0

rx_rf_gain_db

number · double · nullable

The part's own gain, in dB at the connector. TX is an ATTENUATION.

tx_rf_gain_db

number · double · nullable

rx_bandwidth_hz

integer · int64 · nullable

The part's ANALOG filter width, per direction, read from IIO.

NOT a PL register — the AD9361 has none in this address space, which is exactly why the datapath diagram could not show it. None means the attribute could not be read, never a default: this is the value that sat at 18 MHz for a 53 kHz signal (STE-998), and a plausible-looking number here would be worse than an absence.

The part QUANTISES what is written, so this read-back legitimately differs from any requested width. It is the truth; the request is not.

SERIALISED EVEN WHEN NULL, unlike its neighbours above, and the difference is deliberate. An ABSENT field cannot be told apart from an older daemon that never had it; an explicit null says "this daemon knows about the bandwidth and could not read it". For a field whose whole point is that nobody could see it before, that distinction is the feature.

≥ 0

tx_bandwidth_hz

integer · int64 · nullable

≥ 0

sample_rate_sps

integer · int64 · nullable

The part's sample rate. Also on /radio/rf-state; carried here so that one call answers "how is the front end configured" instead of two that have to be reconciled.

≥ 0

Request

curl -X POST "http://192.168.2.1:8080/api/v1/radio/tx<chan>/stop"

Response

{
  "rx_state": "string",
  "tx_state": "string",
  "center_frequency_hz": 0,
  "rx_gain_db": 0,
  "tx_gain_db": 0,
  "loopback": true,
  "timing_lock": true,
  "carrier_lock": true,
  "rx_lo_hz": 0,
  "rx_nco_offset_hz": 0,
  "tx_nco_offset_hz": 0,
  "profile_center_frequency_hz": 0,
  "tx_lo_hz": 0,
  "rx_rf_gain_db": 0.0,
  "tx_rf_gain_db": 0.0,
  "rx_bandwidth_hz": 0,
  "tx_bandwidth_hz": 0,
  "sample_rate_sps": 0
}

↑↓ to moveEnter to open