Skip to content

Multi-panadapter: 2nd panadapter loses FFT spectrum (waterfall continues), cannot be closed — persistent across reboot and sole-client reconnect #268

@chibondking

Description

@chibondking

Multi-panadapter: 2nd panadapter loses FFT spectrum (waterfall continues), cannot be closed — persistent across reboot and sole-client reconnect

Labels: bug, spectrum, priority: high
Related: #152 (multi-panadapter support)

Edit: This is a pretty complicated issue

What

In a specific Multi-Flex scenario involving three slices across two clients,
AetherSDR's second panadapter enters a broken state where:

  1. The FFT spectrum display is blank — no signal trace, no noise floor,
    nothing.
  2. The waterfall continues to scroll and display signals normally.
  3. The broken state persists across radio reboot and across
    AetherSDR-only reconnect (disconnecting SSDR entirely does not
    recover it).
  4. The second panadapter cannot be closed from within AetherSDR while
    in this state.

Scenario That Triggers the Bug

SSDR connects first  → gets Slice A (Pan 1)
AetherSDR connects   → gets Slice B (Pan 1) + Slice C (Pan 2)  [Multi-Flex]

Radio glitches.

Result: Slice C / Pan 2 in AetherSDR shows waterfall only — no FFT spectrum.
        Pan 2 close button is non-functional.
        Rebooting radio does not recover.
        Disconnecting SSDR, reconnecting AetherSDR alone does not recover.

Note: a separate but related bug exists where connecting AetherSDR without
SSDR also results in unexpected slice assignment (should get A & B, gets
different assignments) — see "Related Bugs" section below.


Steps to Reproduce

  1. Connect SSDR to the radio. Confirm it holds Slice A on Pan 1.
  2. Connect AetherSDR in Multi-Flex. Confirm it gets Slice B on Pan 1 and
    Slice C on Pan 2.
  3. Allow or induce a radio glitch (power fluctuation, network hiccup,
    firmware watchdog reset, or rapid connect/disconnect cycling).
  4. After the glitch, observe AetherSDR's Pan 2:
    • Expected: FFT spectrum and waterfall both display normally on Pan 2.
    • Actual: FFT spectrum is blank. Waterfall scrolls normally.
  5. Attempt to close Pan 2 via its close button.
    • Expected: Pan 2 closes and AetherSDR returns to single-pan layout.
    • Actual: close button has no effect. Pan 2 cannot be dismissed.
  6. Reboot the radio. Reconnect AetherSDR.
    • Expected: recovered state — Pan 2 FFT works normally.
    • Actual: blank FFT on Pan 2 persists. State survived the reboot.
  7. Disconnect SSDR entirely. Reconnect AetherSDR as sole client.
    • Expected: recovered state.
    • Actual: blank FFT on Pan 2 still persists.

Why This Is Non-Trivial

The waterfall continuing while the FFT is blank is the critical diagnostic
clue. Both displays are fed from VITA-49 UDP packets but via different
PCCs
:

  • FFT spectrum bins → PCC 0x8003
  • Waterfall tiles → PCC 0x8004

The fact that 0x8004 (waterfall) is arriving and being rendered while
0x8003 (FFT) is not means the VITA-49 stream for Pan 2 is partially
alive. This points to one of:

  1. The radio is sending PCC 0x8004 but not 0x8003 for Pan 2's
    stream ID after the glitch — the radio-side FFT stream for that
    panadapter stalled or was not restarted.
  2. PanadapterStream is receiving 0x8003 packets for Pan 2 but
    routing them to the wrong SpectrumWidget
    — a stream ID mismatch
    after the glitch caused setOwnedStreamIds() to associate Pan 2's
    FFT stream ID with a stale or incorrect value.
  3. SpectrumWidget for Pan 2 is receiving FFT data but not rendering
    it
    — a paint path failure specific to the second widget instance,
    possibly a QWidget::update() call that stopped being invoked after
    the glitch.

The persistence across radio reboot eliminates hypothesis (1) as the sole
cause — if the radio were simply not sending the FFT stream, a reboot
would reset it. The persistence across sole-client reconnect strongly
implicates a corrupt client-side state in AetherSDR that survives
disconnect/reconnect: specifically, a stale stream ID, a broken signal
connection between PanadapterStream and the second SpectrumWidget, or
a PanadapterStack layout state that does not fully reinitialise on
reconnect.

The inability to close Pan 2 is a separate but related symptom: the close
button's handler likely checks a state flag (stream active, model valid,
etc.) that is stuck in an inconsistent value after the glitch, causing the
guard condition to block the close action.


Suggested Debugging Steps

  1. Capture a diagnostic log during the broken state with the
    PanadapterStream logging category enabled. Confirm whether PCC
    0x8003 packets for Pan 2's stream ID are arriving at
    PanadapterStream. If they are arriving but not reaching
    SpectrumWidget, the routing is broken. If they are not arriving, the
    radio stopped sending the FFT stream.

  2. Check setOwnedStreamIds() — after the glitch, confirm that
    PanadapterStream still has the correct Pan 2 FFT stream ID
    (0x8003) registered. If the stream ID changed after the glitch (the
    radio may assign a new stream ID on reconnect) and
    setOwnedStreamIds() was not called with the updated value, all Pan 2
    FFT packets would be silently dropped.

  3. Check PanadapterStack reinitialisation on reconnect — confirm
    that wirePanadapter() is called for Pan 2 on every reconnect, not
    just on initial creation. If the signal connections between
    PanadapterStream and SpectrumWidget for Pan 2 are established once
    at creation and then broken by a disconnect/reconnect cycle without
    being rewired, FFT updates would stop arriving at the widget.

  4. Check the Pan 2 close button handler — identify what condition is
    blocking the close action and why it is stuck after the glitch.


Related Bugs

Separate bug: wrong slice assignment when connecting without SSDR

When connecting AetherSDR as the sole client (SSDR not connected),
AetherSDR should receive Slices A and B. Instead it receives unexpected
slice assignments. This suggests RadioModel's SmartConnect logic
(which calls slice get <id> for existing slices rather than creating
new ones) may be interacting incorrectly with the radio's slice allocation
when no other client session is present. This warrants its own issue but
shares the slice/panadapter assignment code path with the primary bug.


Protocol Hints

VITA-49 stream IDs for Pan 2 (observed values from CLAUDE.md)

  • FFT stream: same as panadapter object ID (e.g. 0x40000001 for Pan 2)
  • Waterfall stream: 0x42000001 for Pan 2

Re-requesting the FFT stream (if radio stopped sending)

// The panadapter create command that established Pan 2's FFT stream:
display panafall create x=100 y=100
// On reconnect, if stream ID changed, AetherSDR must call:
client udpport <port>   // re-register UDP port
// and re-subscribe to the new stream ID

Checking stream registration

Add a log entry in PanadapterStream::setOwnedStreamIds() to capture the
exact FFT and waterfall stream IDs registered for each pan at connect time
and after any reconnect. Compare these against the stream IDs seen in
arriving VITA-49 packets during the broken state.

Relevant source locations

  • src/core/PanadapterStreamsetOwnedStreamIds(), PCC 0x8003
    dispatch path; add logging to confirm Pan 2 FFT packets are arriving
    and being routed
  • src/gui/SpectrumWidgetupdateSpectrum(): confirm it is being
    called for the Pan 2 instance and that QWidget::update() is invoked
  • src/gui/PanadapterStack — pan creation, wirePanadapter() call on
    reconnect, close button handler and its guard condition
  • src/models/RadioModelSmartConnect slice get logic; pan stream
    ID capture and setOwnedStreamIds() call on reconnect

Metadata

Metadata

Assignees

No one assigned

    Labels

    VITA-49VITA-49 UDP streaming: FFT, waterfall, audio, metersawaiting-confirmationFix applied — waiting for reporter to confirm resolutionbugSomething isn't workingmaintainer-reviewRequires maintainer review before any action is takenmulti-panMulti-panadapter layout and slicingspectrumPanadapter and waterfall

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions