Building and testing Dire Wolf KISS TCP on Mac

Macs are not normally convenient for amateur radio but sometimes it’s useful to make it work for some reason. In this post I’m going to show the steps I took to build the Dire Wolf packet modem on macOS Mojave (10.14.1). It’s based loosely on the Mac OS X instructions in the official Dire Wolf User Guide with a few tweaks based on my preferences, such as using Homebrew.

I go into a bit more detail about setting up direwolf.conf for USB serial PTT control and a USB audio device. Finally I show that it actually works by running Xastir on a Raspberry Pi and forwarding the KISS connection to Dire Wolf on the Mac via TCP. I don’t actually know any software I could run directly on the Mac to test it. (But I’d like to write some, which is how I wound up in this situation!) Normally on Linux you’d use the ax25-apps with kissattach.

I’m going to assume the reader is somewhat familiar with the Terminal app and typing commands into it since this is how Dire Wolf is actually used. I also assume the reader knows how to edit text files, even if they have an unusual extension like .conf.

Downloading and Building

  1. Install Xcode using the App Store app.
  2. Run Xcode, and let it install the additional tools it wants when it pops up a dialog.
  3. Install the Command Line tools. The simplest way to do this is to run Terminal and run git --version. If you don’t have the tools it will prompt you to install them.
  4. Install Homebrew if you don’t already have it:
  5. Install portaudio using Homebrew: brew install portaudio
  6. Find a suitable directory to download the Dire Wolf source code, then clone the git repository: git clone
  7. When it finishes, navigate into that folder: cd direwolf
  8. Compile the program: make
  9. (Optional) Check that it worked and you have the compiled Dire Wolf:

    $ ls -l direwolf
     -rwxr-xr-x  1 tk  staff  425272 10 Dec 22:40 direwolf
     $ file direwolf
     direwolf: Mach-O 64-bit executable x86_64
  10. Make a directory to store the compiled program and its configuration file, and copy out direwolf and the template direwolf.conf:

    $ mkdir ~/dw
    $ cp direwolf direwolf.conf ~/dw
  11. You should now be able to run it. I recommend using -t 0 as the ANSI colours may not display well depending your terminal configuration.

    $ cd ~/dw
    $ ./direwolf -t 0
    Dire Wolf version 1.5
    Warning: Could not open 'symbols-new.txt'.
    The "new" overlayed character information will not be available.

Configuring direwolf.conf

While you should read the entire file to see what options are relevant to your particular situation, I only had to add or modify three lines to my copied direwolf.conf. The other defaults were fine for 1200 baud VHF radio.

  1. Change the callsign from N0CALL to something real: MYCALL VK7NTK-2
  2. Find the name of the USB serial device that is controlling PTT. Here I see it is /dev/tty.usbserial-AH00MWQY

    $ ls -l /dev/tty.*
     crw-rw-rw-  1 root  wheel   18,   2  9 Dec 10:50 /dev/tty.Bluetooth-Incoming-Port
     crw-rw-rw-  1 root  wheel   18,   0  9 Dec 10:50 /dev/tty.usbserial-AH00MWQY
  3. Add this to direwolf.conf as a PTT option: PTT /dev/tty.usbserial-AH00MWQY RTS
  4. Run Dire Wolf experimentally and have a look at the audio devices available. Here I see that my dongle is called "Unknown USB Audio Device". The microphone (inputs = 1) is device #4 and the speaker (outputs = 2) is device #3.

    $ ./direwolf -t 0
     Dire Wolf version 1.5
     Warning: Could not open 'symbols-new.txt'.
     The "new" overlayed character information will not be available.
     Reading config file direwolf.conf
     Audio device for both receive and transmit:   (channel 0)
     Number of devices = 5
     ... more devices truncated ...
     --------------------------------------- device #3
     Name        = "Unknown USB Audio Device"
     Host API    = Core Audio
     Max inputs  = 0
     Max outputs = 2
     --------------------------------------- device #4
     Name        = "Unknown USB Audio Device"
     Host API    = Core Audio
     Max inputs  = 1
     Max outputs = 0
     Input device name null
     Pointless to continue without audio device.
  5. Add a line to direwolf.conf setting the input and output audio devices, adding the device numbers to the end after a colon: ADEVICE "Unknown USB Audio Device:4" "Unknown USB Audio Device:3"
  6. Run Dire Wolf again. Provided you are editing direwolf.conf in the same directory it should pick up the new configuration.

    $ ./direwolf -t 0
     Dire Wolf version 1.5
     Warning: Could not open 'symbols-new.txt'.
     The "new" overlayed character information will not be available.

Making it do something

Provided the audio levels are within acceptable bounds, Dire Wolf will start showing decoded packets automatically:

Channel 0: 1200 baud, AFSK 1200 & 2200 Hz, E+, 44100 sample rate.
Ready to accept AGW client application 0 on port 8000 ...
Ready to accept KISS TCP client application 0 on port 8001 ...

Digipeater WIDE2 (probably VK7RTC) audio level = 200(121/129)   [NONE]   |||||||__
Audio input level is too high.  Reduce so most stations are around 50.
[0.3] VK7HSE-1>APRS,VK7RTC,WIDE2*:}VK7RAC>APNU19,TCPIP,VK7HSE-1*:!4057.14SS14543.24E#PHG5520/W3,TASn. NW Tas. Mobile WIDE1-1,WIDE2-2
Warning: Could not open 'tocalls.txt'.
System types in the destination field will not be decoded.
Third Party Header, AMBULANCE

Digipeater VK7RTC audio level = 200(132/127)   [NONE]   |||||||__
Audio input level is too high.  Reduce so most stations are around 50.
[0.3] VK7MBD-12>T3P5W6,VK7HSE-1,WIDE1,VK7RTC*,WIDE2-1:`K*RpH4k/"4{}
MIC-E, TRUCK, Unknown manufacturer, In Service
S 43 05.7600, E 147 14.5400, 51 MPH, course 24, alt 328 ft

What about transmitting? Well, we see from the console output that it supports the KISS protocol and it’s listening on port 8001. Normally TNCs in KISS mode work over a serial port. Indeed, the APRS program Xastir assumes that if you’re using a KISS TNC it’s serial. So let’s trick it.

Here’s the situation that we’re going to set up.

`|'                                    listening        virtual serial port
 |                                     TCP 8001         /tmp/port
 `--[ Radio ]--[Interface]--[Dire Wolf]<<--------[socat]<<--------------[Xastir]
                             ^ Mac                ^---- Raspberry Pi ----^
  1. The radio interface (2x USB) is connected to the Mac.
  2. Dire Wolf listens on port TCP 8001.
  3. On the Raspberry Pi, we run an instance of socat that will create a virtual serial port that forwards any data in and out into a TCP connection back to Dire Wolf. The virtual port will be /tmp/port.
  4. Run Xastir and configure it to use a KISS Serial TNC on port /tmp/port. It ends up using the modem on the Mac, communicating over Ethernet.
  5. Here I’m actually running Xastir via SSH forwarding on the Mac which is slightly ridiculous and not really important to the demonstration. Equivalently you could attach a screen and mouse to your Raspberry Pi and run Xastir on it directly.

socat is not installed by default on Raspbian so make sure it’s installed: sudo apt install socat

Then create the virtual port, forwarding it to Dire Wolf. The trailing & puts the process into the background while we run Xastir. Replace with the IP of the Mac.

$ socat pty,link=/tmp/port,raw tcp: &

Now run Xastir and create the new interface.

Once I press Start to bring up the interface, Dire Wolf shows that it has received some KISS commands from Xastir.

KISS protocol set TXDELAY = 40 (*10mS units = 400 mS), port 0
KISS protocol set Persistence = 63, port 0
KISS protocol set SlotTime = 20 (*10mS units = 200 mS), port 0
KISS protocol set TXtail = 30 (*10mS units = 300 mS), port 0
KISS protocol set FullDuplex = 0, port 0

When I choose Interface > Transmit Now I see that Dire Wolf transmits, both in the terminal and on my radio in real life.

[0L] VK7NTK-2>APX204,WIDE2-2:=4201.2 S/14734.5 E-XASTIR Raspbian<0x0d>

It also shows up in axlisten on my other computer that’s listening on the same frequency, which indicates that my audio output levels are tolerable.

1: fm VK7NTK-2 to APX204 via WIDE2-2 ctl UI pid=F0(Text) len 36 23:11:37                                                                                                 
0000  =4251.3 S/14716.7 E-XASTIR RaspbianM

Wonderful! I now have a full-featured KISS packet modem running on my Mac and have tested that it both sends and receives.

1 Comment

Jeremy Visser
27 Aug 2020

I see you're using socat to connect Xastir to Direwolf.

However, if I'm not mistaken, Direwolf and Xastir appear to support an AGW interface.

Direwolf listens on port 8000 for AGW by default, and if you tell Xastir to add a "Networked AGWPE" interface and connect to port 8000, it should connect.

Does that work for you?