Pat (Winlink) on Linux


For example

curl -L -o pat.tgz
tar -zxvf pat.tgz
sudo mv pat*/pat /usr/local/bin/

Pat Configuration

pat configure
  1. Set your callsign
  2. Set your maidenhead locator

Also setup pat to use hamlib over rigctld (and optionally set it’s http address)

  "hamlib_rigs": {
    "FT-991": {
      "address": "localhost:4532",
      "network": "tcp"
  "http_addr": "localhost:5000"

This assumes you’ve got rigctld already running, and the rig name here matches the 3rd column in $(rigctl -l)

Next tell Pat some rig specifics for ardop (set these in addition to the defaults)

  "ardop": {
    "rig": "FT-991",
    "ptt_ctrl": true

Note the rig name must match your rig mentioned in hamlib_rigs

Then create aliases like these in $(pat configure) (in addition to telnet), and leverage $(pat rmslist) for choices

  "connect_aliases": {
    "ardop-helpful-label": "ardop:///CALLSIGN?freq=14108.5"

Note: The frequency is in kHz, not MHz

Setup Ardop

First download ardopc for your platform. For example:

sudo curl -o $bin
sudo chmod +x $bin

Next configure alsa with specifics for ardop in ~/.asoundrc (this example happens to match my FT-991A)

pcm.ARDOP {
	type rate
	slave {
		pcm "hw:2,0"
		rate 48000

Now you can run ardopc and leave it running (or use systemd)

# Note: The default alsa port it'll use is: ARDOP (in ~/.asoundrc)
# Note: The default port it listens on is 8515, which is what Pat uses by default

You can also find RMS relay stations using ardop via:

# Note: This will cache locally at ~/.wl2k/rmslist.json, refresh with force
# Note: Using -s will sort by distance from your location, so look for ones at the top :)
pat rmslist -s -m ardop --force-download

Run pat

pat http
xdg-open http://localhost:8080


The goal is to use the highest value, but with no visible ALC

  1. Set the radio METER to ALC
  2. Connect to an RMS reflector
  3. Raise the DT GAIN until you see ALC
  4. Then dial it back down until the ALC is no longer visible

For example, I’ve had good luck at 50W with DT Gain of 20

If you don’t yet have a winlink connection, you’ll do the following:

  1. Leave the password field empty in $(pat configure)
  2. Connect via telnet (internet connection needed, no radio needed)
  3. You’ll get a message telling you about your new password
  4. Put that password into your config (and ideally change it)

When connecting to RMS reflectors, there are center and dial frequencies. I’ve read the Winlink FAQ and it really seems to tell you to use the center frequency. That being said, I think you should use the dial frequency. The fact that pat takes the time to formulate the connection string off the dial makes sense… and I’ve tried to connect to both - and I use the dial frequency :)

Overview of path with ax.25

This setup seems reasonably complex. On Linux it goes something like this:

  1. You tell ax.25 about your callsign and some baud rate settings and stuff
  2. You point Direwolf at your radio sound card
  3. You attach an ax.25 port to the resulting Direwolf device
  4. Pat talks to the ax.25 port
  5. I’ve not actually tried this yet… below are just notes while researching it a bit


sudo dnf install direwolf ax25-tools


Edit and write this to /lib/systemd/system/ax25.service

Description=AX.25 KISS interface

ExecStart=/usr/local/bin/ax25-up /dev/ttyUSB0 wl2k 1200

sudo systemctl daemon-reload

Then copy the init file that sets all the bits

sudo curl -o $bin
sudo chmod +x $bin


Append to /etc/ax25/axports (avoid trailing line breaks so it seems)

#portname       callsign        speed   paclen  window  description
wl2k            KJ7PKZ          1200   255     7       Winlink

Follow the upstream docs

# Bring up the device
sudo systemctl start ax25

# Check status/error log
sudo systemctl status ax25 -l

# (optional) Enable the AX.25 interface on startup
sudo systemctl enable ax25

# Bring down the interface
sudo systemctl stop ax25

Watch the ax25 interface for activity:

sudo axlisten -cart

Configure pat

You want pat’s ax25 config to match /etc/ax25/aexports

  "ax25": {
    "port": "wl2k",
    "beacon": {
      "every": 3600,
      "message": "Winlink P2P",
      "destination": "IDENT"

Then create aliases like these in $(pat configure), and leverage $(pat rmslist) for choices

  "connect_aliases": {
    "ax25-callsign1": "ax25://wl2k/callsign1",
    "ax25-callsign2": "ax25://wl2k/callsign2"

References (random order)