All docsStellar LinkRF bench · by Stellar Systems v0.1.0

API Reference

Chain

GET/api/v1/chain

Status#

The complete conditioning verdict, in one call.

Query parameters

target

string · nullable

air, device-loopback or pl-loopback. Defaults to what the board is already wired for.

Responses

200OKapplication/json
targetrequired

string

The target these conditions were computed for.

current_target

string · nullable

What the board is wired for right now; null when the two loopback switches could not be read.

reaches_the_connectorrequired

boolean

Does anything leave the board in this target? False for both loopbacks — the AD9361's internal one returns TX to RX BEFORE the mixers, so no LO, gain or attenuation setting can explain an empty analyser.

stagerequired

string

readyrequired

boolean

next

string · nullable

The first unmet condition and the command to run. null when ready.

conditionsrequired

array of ConditionDRO

Every condition, in the order the bring-up needs them.

ConditionDRO · 8 fields
keyrequired

string

Stable key — dac-source, tx-egress, …

stagerequired

string

The stage this must be satisfied to leave.

sourcerequired

string

board when the value was re-read from a register or an IIO attribute, session when it is this daemon's memory and a restart forgets it.

requiredrequired

string

observedrequired

string

What it is, or could not be read.

verdictrequired

string

met / unmet / unknown. An unknown BLOCKS: a register we failed to read is not a register holding the right value.

breaksrequired

string

What goes wrong when it is unmet, as the symptom the operator will see.

fixrequired

string

The command that clears it.

Request

curl "http://192.168.2.1:8080/api/v1/chain"

Response

{
  "target": "string",
  "current_target": "string",
  "reaches_the_connector": true,
  "stage": "string",
  "ready": true,
  "next": "string",
  "conditions": [
    {
      "key": "string",
      "stage": "string",
      "source": "string",
      "required": "string",
      "observed": "string",
      "verdict": "string",
      "breaks": "string",
      "fix": "string"
    }
  ]
}
POST/api/v1/chain/condition

Condition#

Run the missing conditioning steps, in the one order that works.

WHY AN ENDPOINT AND NOT A RUNBOOK. The order is not a convention, it is a constraint: rf tune resets the sample rate and drives dac_data_sel to PN for its sweep, a mode switch rewrites the ingress gain, and a profile apply rewrites the datapath registers and the LOs. Each step therefore undoes part of the ones before it if taken out of turn — which is exactly the mistake that produced five empty RF passes on 2026-09-09, from a note that stated the rule correctly. A sequence encoded in a function cannot be read in the wrong order.

IT CALLS THE EXISTING HANDLERS, deliberately, rather than repeating what they do. Duplicating rf_mode_air's body here would let the two drift, and the part that would drift is the ordering inside it — the destination is configured fully before the path is switched to it, because mux-first measured 31.28 % against 99.98 %.

Request body application/jsonrequired

target

string · nullable

Where the samples should go. Defaults to air — the only target of the three that puts anything on a connector, and the one an operator at a spectrum analyser is asking for.

profile

string · nullable

Which profile to apply. Defaults to the one currently applied; with none applied the request is refused rather than guessing, because the profile decides the frame length, the coding and the frequency.

rate_sps

integer · int64

AD9361 rate for the tuning step, when one is needed.

≥ 0

Responses

200OKapplication/json
stepsrequired

array of string

The steps actually run, in order.

detailrequired

array of string

What each step reported, keyed in the same order as steps.

staterequired

ChainStateDRO

ChainStateDRO · 7 fields
targetrequired

string

The target these conditions were computed for.

current_target

string · nullable

What the board is wired for right now; null when the two loopback switches could not be read.

reaches_the_connectorrequired

boolean

Does anything leave the board in this target? False for both loopbacks — the AD9361's internal one returns TX to RX BEFORE the mixers, so no LO, gain or attenuation setting can explain an empty analyser.

stagerequired

string

readyrequired

boolean

next

string · nullable

The first unmet condition and the command to run. null when ready.

conditionsrequired

array of ConditionDRO

Every condition, in the order the bring-up needs them.

ConditionDRO · 8 fields
keyrequired

string

Stable key — dac-source, tx-egress, …

stagerequired

string

The stage this must be satisfied to leave.

sourcerequired

string

board when the value was re-read from a register or an IIO attribute, session when it is this daemon's memory and a restart forgets it.

requiredrequired

string

observedrequired

string

What it is, or could not be read.

verdictrequired

string

met / unmet / unknown. An unknown BLOCKS: a register we failed to read is not a register holding the right value.

breaksrequired

string

What goes wrong when it is unmet, as the symptom the operator will see.

fixrequired

string

The command that clears it.

Request

curl -X POST "http://192.168.2.1:8080/api/v1/chain/condition" \
  -H "Content-Type: application/json" \
  -d '{
  "target": "string",
  "profile": "string",
  "rate_sps": 0
}'

Response

{
  "steps": [
    "string"
  ],
  "detail": [
    "string"
  ],
  "state": {
    "target": "string",
    "current_target": "string",
    "reaches_the_connector": true,
    "stage": "string",
    "ready": true,
    "next": "string",
    "conditions": [
      {
        "key": "string",
        "stage": "string",
        "source": "string",
        "required": "string",
        "observed": "string",
        "verdict": "string",
        "breaks": "string",
        "fix": "string"
      }
    ]
  }
}
POST/api/v1/chain/recover

Recover#

Pulse the receiver's CLEAR bits — the recovery that is not a reboot.

WHY THIS IS A ROUTE AND NOT A NOTE. The carrier loop on this bench gets stuck: symbols flow, lock reads true, and the deframer never finds its ASM. The recorded remedy is a CLEAR pulse, after which the RF link frames at ~100 %. Three blocks decode CTRL[1] = clear, the RTL consumes it, and the PS wrote none of them — so the remedy existed only as a reg set typed by hand, and the ordinary answer to a stuck loop was a reboot.

IT REPORTS WHAT IT PULSED, NOT THAT IT WORKED. The reply carries an explicit caveat, because a frame counter that starts moving is not evidence: the ASM is inserted downstream of the payload in the PL, so it counts clean frames over entirely wrong bytes (STE-402). The verdict is a byte-exact loopback.

Responses

200What was pulsed, and what the registers read back
503No PL driverapplication/json

ApiErrorDRO

Request

curl -X POST "http://192.168.2.1:8080/api/v1/chain/recover" \
  -o response.bin

Response

{}

↑↓ to moveEnter to open