aethersdr / aethersdr/AetherSDR

RepeaterBook API integration — map-based repeater browse + load-to-slice/memory

Open
#3,592 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

GUI maintainer-review New Feature priority: low protocol
Dominant language
C++
Stars
221
Forks
117
Avg merge
2d 7h
Merged PRs (30d)
299

Description

Context

Our RepeaterBook API access application was approved (distributed/per-user-token model). This issue tracks planning + implementation of RepeaterBook directory lookups in AetherSDR — populate the active slice and/or Memory channels with output frequency, offset/duplex, and CTCSS/DCS tone from the RepeaterBook directory.

Locked design constraints (from the approved application — non-negotiable)

These were promised to RepeaterBook and must match the implementation:

  • Per-user API tokens, NOT a shared embedded secret. AetherSDR is GPLv3/distributed — an embedded token would be extractable and is explicitly disclaimed. Each operator enters their own RepeaterBook API key.
  • Tokens stored via QtKeychain (Secret Service/Keyring on Linux, Keychain on macOS, Credential Manager on Windows) — never plaintext config. Reuse the existing pattern in src/gui/MqttSettingsDialog.cpp (HAVE_KEYCHAIN, load/savePasswordFromKeychain).
  • User-initiated, on-demand lookups only — no background polling or bulk scraping. Results cached locally; honor published rate limits.
  • User-Agent: AetherSDR/<version> (https://github.com/aethersdr/AetherSDR; kk7gwy@aethersdr.com) — version is CalVer (YY.M.patch), changes every release.

v1 scope (decided)

  • Primary surface: map-based browse. Plot repeaters on the existing Qt map engine (src/gui/map/, from #3565 — the PSK Reporter map's engine); click a marker to load it.
  • Coverage: worldwide from the start — support both the North America and rest-of-world endpoints.
  • Result lands in BOTH: load into the active slice/VFO (tune now) and allow save to a Memory channel (persist).
  • QTH source for 'near me': GPS (reuse the APRS-beacon position source) + manual Maidenhead/lat-lon + current map center.

Key finding — the radio plumbing already exists ✅

Loading a repeater is already a solved path:

  • src/core/MemoryRecallPolicy.cpp already emits the FlexLib slice commands repeater_offset_dir, fm_repeater_offset_freq, fm_tone_mode, fm_tone_value.
  • The Memory record already carries repeaterOffset, toneMode, toneValue (MemoryCsvCompat, MemoryRecallPolicy).

➡️ A RepeaterBook result maps onto the existing Memory record, and the existing recall path applies offset/tone to the slice. Both "load to slice" and "save to memory" reuse this — no new radio-control code needed. The new work is auth + API client + field mapping + map UI.

Open questions / verify before building

  1. Confirm the exact endpoints + query params available under our approved access, and the auth header format for the per-user token. (Assumption: classic export.php / exportROW.php JSON.)
  2. Proximity model. The classic export API is keyed by region (state/county/city), not a lat-lon radius. So "near me" is likely: fetch by admin region, then client-side distance filter/sort around the QTH and center the map there. Confirm whether any radius/bbox query is available; if not, design around region-fetch + client filter.
  3. Documented rate limits — pin the exact numbers; size the cache TTL + throttle to them.
  4. Field mapping — RepeaterBook fields → Memory record (freq, offset sign/magnitude, tone mode CTCSS/DCS + value, callsign, location, mode/FM-only). Enumerate and handle missing/odd values.
  5. DCS vs CTCSS coverage — confirm the slice/tone path handles DCS (digital) codes, not just CTCSS.

Proposed implementation phases

  • Phase 0 — API recon (this issue's first PR): confirm endpoints/params/auth/rate-limits against our approved access; document in docs/. (Principle VIII.)
  • Phase 1 — Token settings: RepeaterBook settings dialog/section; per-user key entry; QtKeychain store (copy MqttSettingsDialog pattern); nested-JSON config per Principle V for non-secret prefs (endpoint region defaults, cache TTL).
  • Phase 2 — API client + cache: RepeaterBookClient (QNetworkAccessManager), correct User-Agent, JSON parse → result model, on-disk cache keyed by query, throttle to rate limits.
  • Phase 3 — Field mapping → Memory record: RepeaterBook result → existing Memory struct; unit-test the mapping (offset sign, tone mode/value, DCS).
  • Phase 4 — Map browse UI: region fetch → markers on the src/gui/map/ engine; QTH from GPS/manual/map-center; client-side proximity filter; marker click → load active slice + 'Save to Memory' action.

Out of scope for v1

  • Writing/contributing data back to RepeaterBook.
  • Background auto-refresh / full offline directory mirror (on-demand + local cache only).
  • Non-map bulk-import wizard and freq/callsign search dialogs (roadmap follow-ups; the client + mapping built here enable them).

Constitution touchpoints

  • Principle V — non-secret prefs as one nested-JSON config object.
  • Secrets — API token in OS keychain, never in config (per approved design).
  • Principle XI — demonstrate the load path end-to-end (mapping unit tests + a real lookup → slice tune).
  • Cross-platform — QtKeychain + QNetworkAccessManager are portable; verify on Linux/macOS/Windows.

cc the core team for design input before Phase 1. Related: #3565 (map engine), Memory subsystem.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Begin with Phase 0 and inspect src/gui/MqttSettingsDialog.cpp for the existing QtKeychain pattern, then review src/gui/map/ and src/core/MemoryRecallPolicy.cpp. The first PR should document the approved endpoints, query parameters, authentication format, rate limits, and field mapping in docs/ before the later implementation phases proceed.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
api, authentication, desktop
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.