graywolf

module
v0.13.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 9, 2026 License: GPL-2.0

README

Graywolf

Graywolf is a modern APRS station with a software modem, digipeater, iGate, and web UI. It bundles everything you need to put an APRS station on the air — from raw audio demodulation to APRS-IS gating — and makes it easy with a browser-based configuration interface.

Download the Latest Release — prebuilt for Linux (Debian/Ubuntu and Fedora/RHEL), macOS, and Windows.

Read the Handbook — installation, configuration, operation guide, and REST API reference.

Known-Working Configurations — community-tested hardware setups with exact settings. Check here for your device, and submit a PR if yours isn't listed.

Graywolf APRS Discord — community chat for help, discussion, and development.

Graywolf is used all around the world! See a map of currently active stations

Written by Chris Snell, NW5W.

The modem is written in Rust and includes a port of the AFSK demodulator from Dire Wolf by WB2OSZ. The decision-feedback AGC and hard-limiter correlator techniques are credited to Ion Todirel (W7ION), from his libmodem.

The AX.25 decoding, APRS operatations (beacons, digipeater, and iGate), and the web API is handled by a service written in the Go programming language.

The web frontend was built in Svelte.

Performance

Graywolf's AFSK demodulator beats Direwolf's best mode (-P AD+) on every track of the WA8LMF TNC test CD, at about 5% of a Raspberry Pi 5.

WA8LMF Track Direwolf Graywolf
01 — 40-min traffic 1020 1026
02 — DE-emphasized Mic-E 1000 1000
03 — flat Mic-E (100 reps) 100 100
04 — drive test 107 108

Reproduce with ./bench.sh.

Features

Graywolf dashboard

  • Modern Web UI - GW is managed via the browser, with a responsive interface that works well on desktops and smartphones.

  • Software Modem - High performance DSP written in Rust that's slightly more effective than Direwolf and much better than most hardware TNCs. Efficeint: uses about 19% of a single CPU core on a Raspberry Pi 5.

  • Live Map - Like having a private aprs.fi for your station. Real-time APRS map with trails, digipeater paths, weather overlays, etc., rendered on our private vector basemap. You can download maps for your state/province/country for offline use!

  • Messages - SMS-style APRS messaging with delivery status and unread badges

    • Direct messages with auto-ACK and retry
    • Tactical callsigns (e.g. GRAYWOLF, AMIGOS) for group nets
    • RF-first delivery with APRS-IS fallback
    • Long messages up to 200 characters
  • Actions - Trigger scripts remotely with specially-crafted APRS messages

    • Can trigger via shell script, Powershell script, or webhook
    • Can be secured with one-time passwords a la Google Authenticator or 1Password
  • Push-to-Talk - Multiple PTT methods for any setup

    • Serial RTS/DTR (Digirig, USB-serial adapters)
    • CM108 USB HID GPIO (AIOC, homebrew sound card adapters)
    • Linux GPIO (Raspberry Pi, BeagleBone)
    • Hamlib rigctld (CAT control)
  • Digipeater - Full-featured APRS digipeater

    • WIDEn-N path handling
    • Preset-driven configuration (fill-in, wide-area, etc.)
    • Duplicate suppression
    • Per-path filtering
  • iGate - Bidirectional APRS-IS gateway

    • RF → APRS-IS and APRS-IS → RF gating
    • Configurable filters
    • Packet origin tracking in logs
  • TNC Interfaces - Speak the protocols other packet software expects

    • KISS TNC (TCP built in; serial via tnc-server)
    • AGWPE TCP interface
  • Beacons and GPS - Position reporting made easy

    • Static and GPS-driven position beacons
    • Status and telemetry beacons
    • Configurable beacon intervals and paths
  • Observability

    • Prometheus metrics
    • Packet logging to SQLite database, with search ability
    • Live packet stream in the web UI
  • Simple installation - single binary, SQLite config database

    • systemd service unit
    • Debian/Ubuntu (APT), Red Hat (RPM), and Arch (AUR) packages
    • Windows installer
    • macOS binaries
    • Runs on x86-64 and ARM (Raspberry Pi)

Directories

Path Synopsis
cmd
flareschema-gen command
Command flareschema-gen prints the JSON Schema document for the flareschema.Flare struct to stdout.
Command flareschema-gen prints the JSON Schema document for the flareschema.Flare struct to stdout.
graywolf command
Package main contains the graywolf subcommand entry point for `graywolf flare`.
Package main contains the graywolf subcommand entry point for `graywolf flare`.
graywolf-pocb command
graywolf-pocb is the POC-B Go stub.
graywolf-pocb is the POC-B Go stub.
graywolf/authcli
Package authcli implements the `graywolf auth` subcommand tree: set-password, list-users, and delete-user.
Package authcli implements the `graywolf auth` subcommand tree: set-password, list-users, and delete-user.
smoke-kiss-tcp-client command
Command smoke-kiss-tcp-client is the in-process driver half of the scripts/smoke/remote-kiss-tnc.sh end-to-end smoke test.
Command smoke-kiss-tcp-client is the in-process driver half of the scripts/smoke/remote-kiss-tnc.sh end-to-end smoke test.
pkg
actions
Package actions implements the Graywolf Actions subsystem: an APRS message-driven trigger surface that dispatches operator-defined commands and webhooks.
Package actions implements the Graywolf Actions subsystem: an APRS message-driven trigger surface that dispatches operator-defined commands and webhooks.
agw
Package agw implements a minimal AGWPE-compatible TCP server for APRS use.
Package agw implements a minimal AGWPE-compatible TCP server for APRS use.
app
Package app is the graywolf composition root.
Package app is the graywolf composition root.
app/ingress
Package ingress defines an in-process typed identifier for the origin of an RX frame flowing through the modem-RX fanout.
Package ingress defines an in-process typed identifier for the origin of an RX frame flowing through the modem-RX fanout.
app/txbackend
Package txbackend contains the per-channel TX dispatcher that replaces the single modem Sender function graywolf used before Phase 3 of the KISS TCP-client / channel-backing plan.
Package txbackend contains the per-channel TX dispatcher that replaces the single modem Sender function graywolf used before Phase 3 of the KISS TCP-client / channel-backing plan.
aprs
Package aprs parses and builds APRS (Automatic Packet Reporting System) packets carried in AX.25 UI frame information fields.
Package aprs parses and builds APRS (Automatic Packet Reporting System) packets carried in AX.25 UI frame information fields.
ax25
Package ax25 implements AX.25 v2.0 UI frame encode/decode.
Package ax25 implements AX.25 v2.0 UI frame encode/decode.
ax25conn
Package ax25conn implements an AX.25 v2.0 / v2.2 LAPB data-link state machine for outbound (client) connections.
Package ax25conn implements an AX.25 v2.0 / v2.2 LAPB data-link state machine for outbound (client) connections.
ax25termws
Package ax25termws bridges a per-WebSocket connection to a pkg/ax25conn session: inbound JSON envelopes from the browser drive the session's event loop; outbound observer events become envelopes pushed back to the browser.
Package ax25termws bridges a per-WebSocket connection to a pkg/ax25conn session: inbound JSON envelopes from the browser drive the session's event loop; outbound observer events become envelopes pushed back to the browser.
beacon
Package beacon implements the graywolf beacon scheduler: position, object, tracker, custom, and igate beacons driven by the configstore `beacons` table, with optional SmartBeaconing for tracker beacons and safe `comment_cmd` execution for dynamic comments.
Package beacon implements the graywolf beacon scheduler: position, object, tracker, custom, and igate beacons driven by the configstore `beacons` table, with optional SmartBeaconing for tracker beacons and safe `comment_cmd` execution for dynamic comments.
callsign
Package callsign provides shared parsing, N0CALL detection, resolution, and APRS-IS passcode computation for amateur-radio callsigns.
Package callsign provides shared parsing, N0CALL detection, resolution, and APRS-IS passcode computation for amateur-radio callsigns.
configstore
Package configstore persists graywolf configuration in a SQLite database via GORM.
Package configstore persists graywolf configuration in a SQLite database via GORM.
diagcollect
Package diagcollect implements the body of the "graywolf flare" subcommand: collect a typed flareschema.Flare from the local install, scrub it, present it for review, and submit it.
Package diagcollect implements the body of the "graywolf flare" subcommand: collect a typed flareschema.Flare from the local install, scrub it, present it for review, and submit it.
diagcollect/redact
Package redact applies privacy scrubbing to a flareschema.Flare after collection and before review.
Package redact applies privacy scrubbing to a flareschema.Flare after collection and before review.
diagcollect/review
Package review presents a scrubbed flare payload to the user and returns their decision (submit / cancel / edit notes / add redaction regex).
Package review presents a scrubbed flare payload to the user and returns their decision (submit / cancel / edit notes / add redaction regex).
diagcollect/submit
Package submit posts a scrubbed flareschema.Flare to graywolf-flare-server.
Package submit posts a scrubbed flareschema.Flare to graywolf-flare-server.
digipeater
Package digipeater implements a WIDEn-N / TRACEn-N APRS digipeater with preemptive digipeating and cross-channel routing driven by per-channel rules stored in the configstore.
Package digipeater implements a WIDEn-N / TRACEn-N APRS digipeater with preemptive digipeating and cross-channel routing driven by per-channel rules stored in the configstore.
flareschema
Package flareschema is the canonical Go definition of the graywolf flare wire payload — the schema-versioned JSON document that the "graywolf flare" CLI submits to graywolf-flare-server.
Package flareschema is the canonical Go definition of the graywolf flare wire payload — the schema-versioned JSON document that the "graywolf flare" CLI submits to graywolf-flare-server.
gps
Package gps provides a unified GPS position cache with NMEA-serial and gpsd (TCP JSON) reader implementations.
Package gps provides a unified GPS position cache with NMEA-serial and gpsd (TCP JSON) reader implementations.
historydb
Package historydb persists station position history in a standalone SQLite database.
Package historydb persists station position history in a standalone SQLite database.
igate
Package igate implements graywolf's APRS-IS iGate: bidirectional gatewaying between the RF side (decoded APRS packets coming out of pkg/aprs as PacketOutput submissions) and the APRS-IS internet backbone.
Package igate implements graywolf's APRS-IS iGate: bidirectional gatewaying between the RF side (decoded APRS packets coming out of pkg/aprs as PacketOutput submissions) and the APRS-IS internet backbone.
igate/filters
Package filters implements the IS->RF gating rule engine.
Package filters implements the IS->RF gating rule engine.
internal/backoff
Package backoff provides an exponential backoff schedule with optional additive jitter and a configurable cap.
Package backoff provides an exponential backoff schedule with optional additive jitter and a configurable cap.
internal/dedup
Package dedup provides a time-windowed deduplication cache suitable for suppressing recently-seen APRS/AX.25 frames across the transmit governor, the digipeater, and the iGate.
Package dedup provides a time-windowed deduplication cache suitable for suppressing recently-seen APRS/AX.25 frames across the transmit governor, the digipeater, and the iGate.
internal/ratelimit
Package ratelimit provides a sliding-window event counter.
Package ratelimit provides a sliding-window event counter.
internal/testsync
Package testsync supplies minimal synchronisation helpers for tests that must wait on real-world, non-logical-time events (TCP accept, goroutine dispatch, counter updates driven by background workers).
Package testsync supplies minimal synchronisation helpers for tests that must wait on real-world, non-logical-time events (TCP accept, goroutine dispatch, counter updates driven by background workers).
internal/testtx
Package testtx provides a shared transmit-sink recorder for tests.
Package testtx provides a shared transmit-sink recorder for tests.
kiss
Package kiss implements the KISS protocol (TNC framing + TCP/serial transports) as specified in Mike Chepponis / Phil Karn's KISS document.
Package kiss implements the KISS protocol (TNC framing + TCP/serial transports) as specified in Mike Chepponis / Phil Karn's KISS document.
logbuffer
Package logbuffer persists graywolf's slog records to a bounded circular buffer in a standalone SQLite database (graywolf-logs.db).
Package logbuffer persists graywolf's slog records to a bounded circular buffer in a standalone SQLite database (graywolf-logs.db).
mapsauth
Package mapsauth is a thin client for auth.nw5w.com, the registration endpoint that issues per-device tokens for the Graywolf private map service.
Package mapsauth is a thin client for auth.nw5w.com, the registration endpoint that issues per-device tokens for the Graywolf private map service.
mapscache
Package mapscache manages on-disk PMTiles archives for offline use.
Package mapscache manages on-disk PMTiles archives for offline use.
mapscatalog
Package mapscatalog fetches the public download catalog from the graywolf-maps Worker (GET <base>/manifest.json) and caches it in-process with a TTL.
Package mapscatalog fetches the public download catalog from the graywolf-maps Worker (GET <base>/manifest.json) and caches it in-process with a TTL.
mapsslug
Package mapsslug owns the namespaced slug grammar for offline-map downloads.
Package mapsslug owns the namespaced slug grammar for offline-map downloads.
messages
Package messages is graywolf's APRS messaging domain.
Package messages is graywolf's APRS messaging domain.
metrics
Package metrics exposes graywolf's Prometheus metrics and a helper to fold Rust-side StatusUpdate messages into them.
Package metrics exposes graywolf's Prometheus metrics and a helper to fold Rust-side StatusUpdate messages into them.
modembridge
Package modembridge supervises the Rust graywolf-modem child process and runs the IPC state machine that drives it from the Go side.
Package modembridge supervises the Rust graywolf-modem child process and runs the IPC state machine that drives it from the Go side.
packetlog
Package packetlog is a bounded in-memory ring buffer of RX/TX/IS packet records with a filtered query API.
Package packetlog is a bounded in-memory ring buffer of RX/TX/IS packet records with a filtered query API.
pttdevice
Package pttdevice enumerates serial ports, GPIO chips, and CM108 HID devices that can be used for push-to-talk control.
Package pttdevice enumerates serial ports, GPIO chips, and CM108 HID devices that can be used for push-to-talk control.
releasenotes
Package releasenotes owns the embedded release-note content that drives the "What's new" popup and About-page section.
Package releasenotes owns the embedded release-note content that drives the "What's new" popup and About-page section.
remoteactions
Package remoteactions implements the OUTBOUND half of the Actions feature: operator-curated macros and TOTP credentials used to fire `@@<otp>#<action> [k=v ...]` invocations at remote stations from inside Messages.
Package remoteactions implements the OUTBOUND half of the Actions feature: operator-curated macros and TOTP credentials used to fire `@@<otp>#<action> [k=v ...]` invocations at remote stations from inside Messages.
txgovernor
Package txgovernor is graywolf's centralized transmit governor.
Package txgovernor is graywolf's centralized transmit governor.
updatescheck
Package updatescheck polls GitHub's releases API once per day and caches the latest-release status in memory so the webapi layer can serve it without outbound network traffic on the request path.
Package updatescheck polls GitHub's releases API once per day and caches the latest-release status in memory so the webapi layer can serve it without outbound network traffic on the request path.
webapi
Package webapi is graywolf's REST management API.
Package webapi is graywolf's REST management API.
webapi/docs
Package docs holds the frozen operation-ID registry for the webapi package's OpenAPI spec.
Package docs holds the frozen operation-ID registry for the webapi package's OpenAPI spec.
webapi/docs/cmd/idlint command
idlint walks pkg/webapi and pkg/webauth, extracts every @ID value appearing in a top-level function's doc comment (via the Go AST — including `/* */` block comments which a plain grep would miss), and asserts that each value is declared as a string constant in pkg/webapi/docs/op_ids.go.
idlint walks pkg/webapi and pkg/webauth, extracts every @ID value appearing in a top-level function's doc comment (via the Go AST — including `/* */` block comments which a plain grep would miss), and asserts that each value is declared as a string constant in pkg/webapi/docs/op_ids.go.
webapi/docs/cmd/tagify command
tagify injects a top-level `tags:` array into the swag-generated OpenAPI 2.0 spec so Swagger UI and downstream generators can render tag groups in a deliberate, curated order instead of alphabetical.
tagify injects a top-level `tags:` array into the swag-generated OpenAPI 2.0 spec so Swagger UI and downstream generators can render tag groups in a deliberate, curated order instead of alphabetical.
webapi/dto
Package dto: actions resource shapes.
Package dto: actions resource shapes.
webauth
Package webauth provides authentication primitives for the graywolf web UI: password hashing, session tokens, and HTTP middleware.
Package webauth provides authentication primitives for the graywolf web UI: password hashing, session tokens, and HTTP middleware.
webtypes
Package webtypes holds types shared across web-facing packages.
Package webtypes holds types shared across web-facing packages.
Package web embeds the built Svelte UI (web/dist) into the graywolf binary.
Package web embeds the built Svelte UI (web/dist) into the graywolf binary.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL