Skip APRS packets whose ts_ms is older than 120 seconds. Live RF-decoded
packets arrive within milliseconds; history replay items can be up to 24
hours old and must not be re-uploaded to APRS-IS as live traffic.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Rewrite the PSKReporter uplink to match the protocol spec exactly:
- Fix template FlowSetIDs: receiver uses 0x0003 (Options Template Set),
sender uses 0x0002 (Template Set); previously both used 0x9992/0x9993
- Add missing enterprise numbers (0x0000768F = 30351) to all enterprise
field specifiers in both template blocks
- Fix sender template field IDs: use correct attributes (senderCallsign
30351.1, frequency 30351.5, sNR 30351.6, iMD 30351.7, mode 30351.10,
informationSource 30351.11, senderLocator 30351.3, flowStartSeconds 150)
- Fix sender data field order to match the template declaration
- Add iMD byte (0) required by the 8-field template
- Add 4-byte null padding on receiver and sender data records
- Batch spots into one UDP packet per 5-minute window (spec requirement)
- Deduplicate by callsign within each window (keep most-recent spot)
- Send template descriptors only in first 3 packets then once per hour
- Increment sequence number by report count, not packet count
- Guard against history replays: drop any spot older than the flush
window (live FT8/WSPR is seconds old; history can be 24 h old)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Rebuild the visible-source chips when live APRS, AIS, or VDES markers are first added so the map filter list updates without a page refresh.\n\nCo-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Use an unbounded virtual-channel command queue so background decode and scheduler transitions do not silently drop subscribe or remove commands.\n\nCo-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Remove hidden background decode channels when the owning audio client disconnects to avoid stale DSP and decoder buildup.\n\nCo-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Run FT8 and WSPR decode steps in blocking sections so the server listener stays responsive under decode load.\n\nCo-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Replace the misleading scheduler task countdown with the actual time-span interleave switch timing in the main controls row.
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Raise remote spectrum polling from 100 ms to 50 ms while keeping the relaxed timeout and subscriber gating.
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Relax the remote spectrum timeout, poll at the backend update cadence, and stop polling when no spectrum subscribers are connected.
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Add separate map path toggles, move scheduler handoff into the channels row, and show a live countdown to the next scheduler cycle.
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Remove settings rig pickers, restore the last scheduler cycle on release, fix FT8 locator role parsing, and add toggleable decode contact paths on the map.
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Move Scheduler under a new Settings tab in the HTTP frontend.
Add the virtual-channel audio implementation plan document.
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Use the active channel frequency for spectrum bandwidth edge hit-testing.
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Each RDS PS overlay item (position: absolute within the shared #rds-ps-overlay
container) now receives a z-index derived from its channel frequency: items are
sorted by freq_hz ascending so higher-frequency layers sit on top of
lower-frequency ones by default.
Hovering any layer temporarily assigns it the maximum z-index (entry count + 10)
to bring it to the front; mouseleave restores the frequency-derived default
stored in data-default-z.
Also reverts the incorrectly applied vchan picker layer changes from the
previous commit.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Render virtual channels as absolutely-positioned layer strips inside a
shared relative container (#vchan-freq-layers). Layers are sorted by
frequency ascending so higher-frequency channels receive a higher z-index
and sit on top by default. Hovering any layer temporarily assigns it the
maximum z-index to bring it to the front; leaving restores the original
stacking order. Each layer is offset by 11 px vertically so all channels
remain visible as a staggered card stack.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Update test fixtures to include hf_aprs_decode_enabled and use the current spectrum watch sender type in remote client tests.
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Add client-side command plumbing, HTTP endpoint handling, and frontend interception so bandwidth changes are applied per active virtual channel and survive reconnects.
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>