[[https://n6cta.com/2023/10/16/linux-packeteering-getting-started/|reformatting from N6CTA's blog post]]
====== Direwolf and LinBPQ on Raspberry Pi ======
====== Preface ======
This is largely derived from the first post N6CTA wrote 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 was geared towards meeting the goal of setting up a well functioning, always-on, reboot safe, packet bulletin board system. When possible, we've 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 if you have minimal Linux experience, but those with linux chops and BBS experience can likely get it all sorted in just a few hours. There’s no sugar coating the config files -- but taken as-is on a clean system, they should work well.
===== Why Direwolf? =====
N6CTA choose to use Direwolf as the software modem in this series as it appeared to the most performant and stable 300Bd FX.25 soft modem available for Linux. We've also investigated ''QtSoundModem'' and found it to be a little more challenging to use. 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 does not appear to be implemented properly in BPQ.
===== Note on Debian as the OS =====
Note: I am listing Debian package 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. In the case of using a Raspberry Pi, it makes more sense to me to use Raspberry Pi OS (Debian Bookworm fork as of this writing) and compile the new software from source. We're recommending compiling from source for these components in order to get the latest and greatest, although this requires a little extra work to get set up and chance for new bugs.
//Boilerplate yadda yadda, YMMV. Let’s get on with it. //
====== Choice of PC or Raspberry Pi? ======
//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. We're using a Raspberry Pi 4B because they are fairly common and easily available, while also aware there is ongoing discourse around very poor behavior and a scandalous staffing decision by the Raspberry Pi Foundation -- so we're not suggesting to go out and buy a Raspberry Pi just for this. Start with looking for a suitable candidate sitting in a closet or can score one at an e-waste roundup or surplus store.
Reasons to choose a Raspberry Pi for N6CTA's original project:
* 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
* Other SBC's have varying level of update support for their OS, Raspberry Pi is consistently good about theirs
* The SBC can easily be powered by my portable radio battery
* Eventually solar power the whole shebang so managing power consumption is important to me
====== Setting up the OS ======
===== On a Pi... =====
If you’re following along with a Pi, we 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.
===== Other hardware? =====
If you’re undecided about what linux disto to use and you’re on some other hardware, //We 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.
//But really we should say a bit more?//
===== Directories =====
We recommend setting up the software with these directories:
cd ~/.local && mkdir bin log src
cd ~/.local/share/ && mkdir icons
cd ~/.config && mkdir autostart linbpq direwolf qttermtcp hamlib
We'll use the ''bin'' directory for the executables we build later, the ''log'' directory for logs, and the ''src'' directory for the source code that we compile. The ''share/icons'' directory is used by BPQ, and the configuration files will live in the appropriate subdirectory of ''~/.config/'' for each program.
You may have your own preference for these, but we'll follow this for the rest of the tutorials.
===== Installing dependencies =====
We recommend updating your system before we proceed and retrieving an up-to-date package list.
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
===== Configuring for a "remote" machine =====
if you're going to run this on a "headless" without a monitor, or a "remote" machine that you leave in your shack, while accessing from elsewhere, you'll want to enable the correct settings to join the network and start a VNC server (if you want to use the GUI applications recommended). This isn't strictly necessary, but nice to have.
If you're on a Raspberry Pi, run:
sudo raspi-config
If you're on another system, you'll need to follow tutorials found elsewhere online.
And then configure 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
====== Compiling the pieces ======
The various components we need to use are all open source, and we recommend grabbing the latest source code to build yourself. You can do this by running the following:
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
It doesn't hurt to download and build all of these, it doesn't add much time to the process. But if you want to trim down what you install:
* ''direwolf'' is essential, and ''linbpq'' is required to run a BBS. If you only plan to connect to other nodes as a client, you can stick to just ''direwolf''.
* ''hamlib'' is only required if you want to remotely control the transceiver to switch frequencies or other settings.
* ''sunwait'' is optional but useful if you want to configure band-switching around the time the sun sets each day.
* ''QtTermTCP'' is recommended, but other packet terminal applications can be used and we have been investigating the other options but found this to be the best.
Next we'll compile these pieces.
//If you’re compiling on a pi ‘make -j4’ will allow you compile using all four cores which significantly speeds things up.//
We recommend building in this order.
===== Hamlib =====
cd ~/.local/src/Hamlib/
./bootstrap
./configure
make
export
sudo make install
===== linbpq =====
cd ~/.local/src/linbpq/
make
cp linbpq ~/.local/bin/
cp *.ico ~/.local/share/icons/
===== QtTermTCP =====
cd ~/.local/src/QtTermTCP/
qmake
make
cp QtTermTCP ~/.local/bin/
cp QtTermTCP.ico ~/.local/share/icons/
===== direwolf =====
cd ~/.local/src/direwolf
mkdir build && cd build
cmake ..
make
sudo make install
sudo make install-conf
===== sunwait =====
cd ~/.local/src/sunwait/
make
cp sunwait ~/.local/bin/
When you're done, you should run ''sudo ldconfig ~/.local/bin/'' to register the shared libraries created by Hamlib.
===== QtTermTCP Desktop/Menu Icon =====
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. This file to create this is located at ''~/.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
====== Audio - ALSA, not Pulse ======
If you’re on anything but a Pi you may be able to disregard this but be sure to check first. It’s best to remove PulseAudio on Pi’s currently, and we'll configure ''alsa'' instead.
sudo apt purge pulseaudio -y && sudo apt autoremove -y && sudo rm -rf ~/.pulse
Next we'll configure ALSA -- despite the jokes on the Internet, Linux audio isn't //that bad// for a simple case like ours. That said, you’ll need to do some experimenting here but it shouldn’t be all that different from what we 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 or you can run 'arecord -l' and 'aplay -l' to get a list of devices.
For example, run ''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 you can set the default index for your USB audio card to force it to a consistent reboot safe value for the ALSA configuration. With only one USB audio device (the rig audio interface) this works well.
Edit ''/etc/modprobe.d/alsa-base.conf'' to add:
options snd_usb_audio index=3
Edit your ''/etc/asound.conf'' file to add a hardware alias to this device.
pcm.scu {
type hw
card 3
device 0
rate 44100
}
====== rigctld for CAT/CIV ======
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/CIV interface to play with.
You’ll need to change:
* ''USER'' to your username
* ''YOUR_RIG'' You’ll need to find the number for your rig by running ''rigctld -l | less''
* ''CAT_DEVICE'': You’ll need to find your USB CAT/CIV device with ''ls /dev/ | grep tty''. Likely it is ''/dev/ttyUSB0'' unless you have other USB serial devices plugged in.
First we'll setup a ''systemd'' service for ''rigctld'' to make sure it comes up at boot, by creating the file ''/etc/systemd/system/rigctld.service'' with the following contents:
[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
Then enable and start the service with:
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'' (the program's standard output). 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
====== udev rules for your transceiver ======
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.
Start by running ''udevadm info -q property -n /dev/ttyUSB0'', which will return information about the USB device:
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:
From there we want to grab some unique information to help identify this device as our transceiver and create a ''udev'' rules file for the device that'll give it a meaningful and consistent name.
Add some variation of the following to a file in ''/etc/udev/rules.d/'' such as this example called ''80-yaesu-scu17.rules'', using information about the device from ''udevinfo'' above:
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"
After creating the file, run ''sudo udevadm control --reload'' to create a new device called ''/dev/yaesucat''.
====== What's Next? ======
After following this tutorial you should have a 'reboot safe' hardware configuration, making it easier to configure various amateur radio applications for use with FARPN.
From here, you should configure QtTermTCP or another packet client and try connecting to a node!