- C 97.3%
- CMake 1.9%
- Makefile 0.8%
| .github/workflows | ||
| include | ||
| libs | ||
| src | ||
| systemd | ||
| test | ||
| .clinerules | ||
| .gitignore | ||
| .gitmodules | ||
| CMakeLists.txt | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
| sample.conf | ||
| test.log | ||
miniwolf
Danger! Parts of the code and docs may be LLM-written.
What it is
Soundcard modem/TNC for amateur radio packet communications designed as a simple, lightweight alternative to well-known and respected Direwolf by WB2OSZ.
It supports encoding and decoding AX.25 packets over 1200 baud AFSK while interfacing with existing tools over stdin/stdout, TCP, UDP as well as their IPC equivalents with Unix domain sockers. On each of these "interfacing layers" both TNC2 and KISS can be used.
What it isn't
This project is not a:
- Drop-in replacement for Direwolf
- Configuration files and command line arguments are not compatible
- Cross-platform program
- It is built around ALSA, the Advanced Linux Sound Architecture, the implication is fairly obvious
- Multi-mode modem (for now)
- Only Bell202 / 1200 baud AFSK is supported
- Perhaps most importantly: Fully-featured APRS station
- No built-in digipeating, beaconing, APRS-IS connectivity
This is the point! To have a focused tool that does one job well. Let other tools figure out the rest.
APRX is one compatible implementation of digipeating, cross-digipeating, beaconing, bidirectional gateway, telemetry and probably more.
I don't know of any smaller tools which serve subsets of these functionalities, hence I'll be trying to provide such tools as well. For example axdigi implements explicit, implicit traced and untraced digipeating, while aprsfmt can format APRS packets and in conjunction with cron, netcat or socat easily provides beaconing.
Build and installation
While cloning the project is entirely standard, the building differs slightly from other projects using CMake. A root-level Makefile is specified with some shortcuts for building and even installing.
Prerequisites
- Linux
- GCC or Clang
- CMake
- ALSA development libraries (
libasound2-devon Debian/Ubuntu)
First steps may go like this:
git clone https://github.com/xdab/miniwolf.git
cd miniwolf
git submodule update --init --recursive
make build # builds with debug flags
make release # builds properly
make install # builds in release mode and installs to the system
Sample usage
# List available audio devices
miniwolf -l
# Receive and transmit with TCP KISS server on port 8100
miniwolf -d "default" -io -r 44100 --tcp-kiss 8100
# Use configuration file
miniwolf -c ~/miniwolf.conf
Command line arguments
Audio setup
| Short option | Long option | Description |
|---|---|---|
-l |
--list |
List audio devices and exit |
-d NAME |
--dev=NAME |
Audio device name (e.g., "default", "hw:1,0") |
-r RATE |
--rate=RATE |
Sample rate in Hz (typically 44100 or 48000) |
-i |
--input |
Enable audio input (receive) |
-o |
--output |
Enable audio output (transmit) |
Protocol
| Short option | Long option | Description |
|---|---|---|
-k |
--kiss |
Use KISS protocol instead of TNC2 for stdin/stdout |
Network
| Long option | Description |
|---|---|
--tcp-kiss PORT |
Start TCP server for KISS clients |
--tcp-tnc2 PORT |
Start TCP server for TNC2 clients |
--udp-kiss-addr ADDR / --udp-kiss-port PORT |
Send received packets via UDP (KISS) |
--udp-tnc2-addr ADDR / --udp-tnc2-port PORT |
Send received packets via UDP (TNC2) |
--udp-kiss-listen PORT |
Listen for KISS packets to transmit via UDP |
--udp-tnc2-listen PORT |
Listen for TNC2 packets to transmit via UDP |
Signal processing
| Short option | Long option | Description |
|---|---|---|
-s VAL |
--squelch=VAL |
Squelch strength (float in range 0.0-1.0, larger means more strict) |
--eq2200 GAIN |
Apply gain at 2200 Hz in dB (use with mw_cal to find optimal value) |
|
--tx-delay MS |
Transmit preamble duration in milliseconds (default: 300) | |
--tx-tail MS |
Transmit postamble duration in milliseconds (default: 50) |
Other
| Short option | Long option | Description |
|---|---|---|
--exit-idle S |
Exit if no packets received for S seconds | |
-v |
--verbose |
Verbose logging |
-V |
--debug |
Debug logging |
Configuration file
Optionally, configuration can be read from a file using -c FILE or --config=FILE.
The file uses simple key=value syntax with # comments.
Keys in the file are the same as long option names of CLI arguments.
File-based configuration is secondary to CLI arguments. Arguments override entries in the configuration file.
Example
# CLI
miniwolf -d "hw:1,0" -io -r 48000 -k -s 0.5 --eq2200 2.5 --tcp-tnc2 8101 --udp-tnc2-addr 127.0.0.1 --udp-tnc2-port 8001
is equivalent to:
# Equivalent.conf
dev=hw:1,0
input=true
output=true
rate=48000
kiss=true
squelch=0.5
eq2200=2.5
tcp-tnc2=8101
udp-tnc2-addr=127.0.0.1
udp-tnc2-port=8001
Working principles
Signal chain
Receive: Audio input → EQ → Squelch → Demodulators → Bit-clock recovery → HDLC deframe → Output
Transmit: Input (stdin/TCP/UDP) → Protocol parse → AX.25 → HDLC encode → FSK modulate → Audio output
Protocol implementation (AX.25, HDLC, KISS, TNC2, CRC-CCITT) resides in libtnc git submodule.
Calibration
Use mw_cal to find the optimal --eq2200 value for your radio:
mw_cal -d "hw:1,0" -r 48000
This displays real-time spectrum analysis with 8 frequency bins, using 1200 Hz as the reference (0 dB). Adjust whatever you've got available to try and make the 1200 and 2200 Hz bins equal. Otherwise, try to use --eq2200 to compensate.
# If 2200 Hz shows -5 dB relative to 1200 Hz, add +5 dB boost
miniwolf -d "hw:1,0" -io -r 48000 --eq2200 5.0
License
GNU General Public License v3.0 - see LICENSE
Development notes: See .clinerules for AI-friendly instructions.