Table of Contents:
- Preface
- Choice of PC
- Installing the OS
- Setting up Directories
- Installing Dependencies
- raspi-config Settings
- Cloning the Source
- Compiling Software
- Dealing with PulseAudio
- .desktop Files
- rigctld Service
- ALSA Settings
- What Next?
Preface:
This is the first post in a series detailing how to get on HF with packet radio using John Wiseman, G8BPQ’s suite of PBBS software, and John Langner, WB2OSZ’s software TNC, Direwolf using the linux operating system. Much of the series is geared towards meeting the goal of setting up a well functioning, always-on, reboot safe, packet bulletin board system. I have tried to denote what is optional and what is not depending on the goal of being either a casual K2K OP with maybe an account on someone else’s machine or being the sysop of a full service HF BBS.
This is likely a weekend project at minimum for the uninitiated but those with linux chops and BBS experience can likely get it all sorted in just a few hours. I have tried to make this as simple as possible but I can guarantee that some of this will make your eyes glaze over. There’s no sugar coating the config files. If you stick with the series, you should have a working BBS system which I think is worth the effort.
I chose to use Direwolf as the software modem in this series as it the most performant 300Bd FX.25 soft modem available for linux at the time of this writing. QtSoundModem at some later date may be worth looking into but I found it to be buggy on both transmit and receive. The difference in real world performance was fairly drastic for me. This is still an imperfect solution as Direwolf doesn’t integrate as cleanly as it could with BPQ’s AGW driver. BPQ treats Direwolf (and all AGW ports) like a KISS TNC instead of allowing the TNC to handle some of the AX.25 stuff it’s good at. WB2OSZ’s OSI comments on why L1 and L2 need to be tightly coupled make a lot of sense and the AGW protocol allows for this kind of behavior but it’s not implemented properly in BPQ. I don’t know why it’s like this. Decisions were made. 🤦🏻♂️
Note: I am listing Debian package maintainer’s names for the libraries throughout the series. If you’re on some other flavor, you’ll likely need to sort out the exact package names from your distribution’s repository. No exotic libraries are being used though and if you can live with using your distribution’s versions of some of this software, by all means, use your repository’s packages. As this is hobby and not a mission critical endeavor, I prefer to play with the latest, and potentially unstable, software which means either using a rolling release distro or compiling from source. In the case of using a Raspberry Pi, as I am in this series, it makes more sense to me to use Raspberry Pi OS (Debian Bookworm fork as of this writing) and compile the new software I want from source. Boilerplate yadda yadda, YMMV. Let’s get on with it. 😉
Choice of PC:
Don’t overthink this part. You can likely use any machine built in the last 15-20 years. As long as it has the ports you need to connect it to your gear, it should be fine. The software isn’t particularly resource intensive. I’m choosing to use a Raspberry Pi 4B because it’s what I have. I’m aware there is ongoing discourse around very poor behavior and a scandalous staffing decision by the Raspberry Pi Foundation. I’m not telling anyone to go out and buy a Pi or any computer really. You likely have a suitable candidate sitting in a closet or can score one at an e-waste roundup.
I choose Pi’s for station computers because:
- I already have a bunch for prototyping work from before the pandemic chip shortage
- Were relatively inexpensive when I bought them
- Raspberry Pi OS is fairly stable now with a vast repository of working software
- The SBC can easily be powered by my portable radio battery
- I want to eventually solar power the whole shebang so managing power consumption is important to me
Installing the OS:
If you’re following along with a Pi, I wholeheartedly recommend using the Pi Imager tool to flash your memory card with.
In Pi Imager you’ll want to click on the gear icon and set:
- Set hostname
- Enable SSH
- Set user and password
- Set locale
- Configure Wireless LAN if necessary
We’ll be using 32-bit software and OS as John doesn’t have stable 64-bit software out for all of the tools and the 64-bit release of Raspberry Pi OS isn’t stable yet. You can use a “lite” or “netinst” OS version if you’d like to but you won’t have the advantage of using QtTermTCP unless you install a window manager or desktop environment of some sort. The server daemon parts can be set up headless if you want to run the client side software over a network instead of via VNC. You can split the installation into client/server if you’d like to. This can easily be done using PiVPN so you can access (remote control – FCC 👀) your BBS from anywhere you have an internet connection.
If you’re undecided about what linux disto to use and you’re on some other hardware, I recommend plain old Debian. It’ll run smoothly on just about everything that isn’t in a museum. Just slap it on a USB stick using your OS’s disk imager of choice and let ‘er rip. It’s the DOOM of OS’s. I ran it continuously on my station computer until recently which was a very tired i386 eeepc netbook from 2008.
Setting up Directories:
This may or may not be controversial for old heads but this is how I recommend setting things up.
cd ~/.local && mkdir bin log src
cd ~/.local/share/ && mkdir icons
cd ~/.config && mkdir autostart linbpq direwolf qttermtcp hamlib
Installing Dependencies:
On first boot after an installation I like to get things up to date as the install media is likely behind.
sudo apt update -y && sudo apt upgrade -y && sudo apt dist-upgrade -y && sudo apt autoremove -y && sudo apt clean -y && sudo reboot
When the machine reboots, the following is what you need to install to compile everything we’re going to use from source.
sudo apt install -y qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5serialport5 libqt5serialport5-dev libfftw3-dev libasound2-dev libpcap-dev libminiupnpc-dev libconfig-dev autoconf libtool git gcc g++ make cmake libudev-dev qtmultimedia5-dev libreadline-dev libusb-1.0-0-dev libavahi-common-dev libavahi-client-dev libgps-dev
raspi-config Settings:
sudo raspi-config
You’ll want to set the following:
- System Options>Network at Boot
- System Options>Boot to Desktop (auto login)
- Interface Options>Enable VNC
- Display Options>VNC Resolution>1080p
If you want RealVNC instead of WayVNC you’ll need to go back to Openbox WM with X11:
- Advanced Options>Wayland>X11
- Install RealVNC from the RealVNC website
Cloning the Source:
cd ~/.local/src/
git clone https://github.com/risacher/sunwait.git
git clone git://vps1.g8bpq.net/linbpq
git clone https://github.com/wb2osz/direwolf.git
git clone git://vps1.g8bpq.net/QtTermTCP
git clone https://github.com/Hamlib/Hamlib.git
Compiling the Source:
If you’re compiling on a pi ‘make -j4’ will allow you compile using all four cores which significantly speeds things up.
cd ~/.local/src/Hamlib/
./bootstrap
./configure
make
export
sudo make install
cd ~/.local/src/linbpq/
make
cp linbpq ~/.local/bin/
cp *.ico ~/.local/share/icons/
cd ~/.local/src/QtTermTCP/
qmake
make
cp QtTermTCP ~/.local/bin/
cp QtTermTCP.ico ~/.local/share/icons/
cd ~/.local/src/direwolf
mkdir build && cd build
cmake ..
make
sudo make install
sudo make install-conf
cd ~/.local/src/sunwait/
make
cp sunwait ~/.local/bin/
Dealing with PulseAudio:
If you’re on anything but a Pi you may be able to disregard this but I would be sure to check first. It’s best to remove it on Pi’s currently. I’m not sure if this will ever be fixed properly for realtime audio applications.
sudo apt purge pulseaudio -y && sudo apt autoremove -y && sudo rm -rf ~/.pulse
.desktop Files:
Here are some suggestions for basic .desktop file entries for QtTermTCP. You’ll need to replace USER with your username. This will give you a nice shortcut in the applications menu.
nano ~/.local/share/applications/qttermtcp.desktop
[Desktop Entry]
Name=QTTermTCP
Path=/home/USER/.config/qttermtcp/
Exec=QtTermTCP
Icon=/home/USER/.local/share/icons/QtTermTCP.ico
Terminal=false
Type=Application
rigctld:
Configuring rigctld is a crucial step to getting the rest of this setup running smoothly. The exact commands may be a little different depending on your gear. What we need is rigctld running in the background to give us a CAT interface to play with.
You’ll need to edit:
- USER to your username
- YOUR_RIG
- You’ll need to find the number for your rig
- rigctld -l
- You’ll need to find the number for your rig
- CAT_DEVICE
- You’ll need to find your USB CAT device.
- ls /dev/ | grep tty
- It’s likely /dev/ttyUSB0
- You’ll need to find your USB CAT device.
sudo nano /etc/systemd/system/rigctld.service
[Unit]
Description=rigctld Start Script
After=network.target
[Service]
Restart=always
RestartSec=20
StartLimitInterval=60
StartLimitBurst=3
User=USER
Group=USER
ExecStart=rigctld -m YOUR_RIG -r CAT_DEVICE
SyslogIdentifier=rigctld-Debug
[Install]
WantedBy=multi-user.target
You’ll need enable the service, and start it.
sudo systemctl enable rigctld.service
sudo systemctl start rigctld.service
If for whatever reason you need to make an edit to a systemd service entry you’ll need to reload systemd and start the service again.
sudo systemctl daemon-reload
sudo systemctl restart rigctld.service
To check on the status of a service we use the ‘status’ command. At the bottom of the output we’ll get essentially a tail of stdout. This is super handy for checking out issues.
sudo systemctl status rigctld.service
If we want to get really fancy we can get a running live log of the service using journalctl. The -u option gives a ‘tail -f’ like output. I use this so much I have a short alias for watching the output of my BBS services. I much prefer this to using screen because we get logging for troubleshooting and many of these daemons cannot take terminal input once run anyway.
journalctl -u rigctld.service
To make it reboot safe I would make a udev rule. Here is an example of mine. I use /dev/yaesucat as my CAT device in the above systemd entry as result of the entry below. The general idea is that you find a specific device identifier using the command below. This was a little tricky as the SCU-17 has two serial devices with the same hardware serial number so my goto identifier didn’t work in this case.
udevadm info -q property -n /dev/ttyUSB0
DEVPATH=/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.3/1-1.3.1/1-1.3.1:1.0/ttyUSB0/tty/ttyUSB0
DEVNAME=/dev/ttyUSB0
MAJOR=188
MINOR=0
SUBSYSTEM=tty
USEC_INITIALIZED=9023171
ID_BUS=pci
ID_VENDOR_ID=0x1106
ID_MODEL_ID=0x3483
ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
ID_PCI_INTERFACE_FROM_DATABASE=XHCI
ID_VENDOR_FROM_DATABASE=VIA Technologies, Inc.
ID_MODEL_FROM_DATABASE=VL805 USB 3.0 Host Controller
ID_PATH=platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3.1:1.0
ID_PATH_TAG=platform-fd500000_pcie-pci-0000_01_00_0-usb-0_1_3_1_1_0
ID_USB_MODEL=CP2105_Dual_USB_to_UART_Bridge_Controller
ID_USB_MODEL_ENC=CP2105\x20Dual\x20USB\x20to\x20UART\x20Bridge\x20Controller
ID_USB_MODEL_ID=ea70
ID_USB_SERIAL=Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_011F3FE4
ID_USB_SERIAL_SHORT=011F3FE4
ID_USB_VENDOR=Silicon_Labs
ID_USB_VENDOR_ENC=Silicon\x20Labs
ID_USB_VENDOR_ID=10c4
ID_USB_REVISION=0100
ID_USB_TYPE=generic
ID_USB_INTERFACES=:ff0000:
ID_USB_INTERFACE_NUM=00
ID_USB_DRIVER=cp210x
ID_MM_CANDIDATE=1
DEVLINKS=/dev/yaesucat /dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3.1:1.0-port0
TAGS=:systemd:
CURRENT_TAGS=:systemd:
sudo nano /etc/udev/rules.d/80-yaesu-scu17.rules
ENV{MAJOR}!="?*", GOTO="yaesucat_rules_end"
SUBSYSTEMS=="usb-serial", GOTO="yaesucat_usb_rules"
GOTO="yaesucat_rules_end"
LABEL="yaesucat_usb_rules"
# YAESU SCU-17
ENV{ID_USB_INTERFACE_NUM} == "00", SYMLINK+="yaesucat", MODE="660", GROUP="dialout"
LABEL="yaesucat_rules_end"
sudo udevadm control --reload
ALSA Settings:
You’ll need to do some experimenting here but it shouldn’t be all that different from what I have below. You’ll need to know the sample rates supported by your device though. If you poke around in /proc/asound/ you’ll find your card.
cat /proc/asound/card3/stream0
Burr-Brown from TI USB Audio CODEC at usb-0000:01:00.0-1.3.2, full speed : USB Audio
Playback:
Status: Running
Interface = 1
Altset = 1
Packet Size = 192
Momentary freq = 48000 Hz (0x30.0000)
Interface 1
Altset 1
Format: S16_LE
Channels: 2
Endpoint: 0x02 (2 OUT) (ADAPTIVE)
Rates: 32000, 44100, 48000
Bits: 16
Channel map: FL FR
This is how I set the default index for my USB audio card to force it to a consistent reboot safe value for my ALSA config. I only have one USB audio device so this works well.
sudo nano /etc/modprobe.d/alsa-base.conf
options snd_usb_audio index=3
This is how I have my asound.conf hardware alias configured for the most basic of setups such as this.
sudo nano /etc/asound.conf
pcm.scu {
type hw
card 3
device 0
rate 44100
}
What Next?:
In the next post in the series we’ll go over everything necessary to get started working HF packet!