Introduction
This post aims to explain how to set up a basic Linux NET/ROM node for participation in Amateur Packet Radio.
Lines starting with $ are commands to be typed.
I'll be using a Raspberry Pi 3 running the current Raspberry Pi OS at the time of writing (bullseye), and a NinoTNC USB KISS TNC. These instructions will likely work for Debian and other debian-dervied systems, and other KISS TNCs including soundmodem and direwolf, but they will require their own configuration be done first.
I've also written an ansible role to perform the same steps described here.
SSIDs and aliases
AX.25 identifies ports using Amateur Radio callsigns. As it is often necessary to have more than one port or station, Secondary Station Identifiers (SSIDs) are used. These take the form of CALLSIGN-NUMBER.
The number can be from 0 to 15. When 0 is used it is typically ommited when the SSID is displayed and just CALLSIGN is shown.
While SSIDs can be used for anything there are some conventions associating particular numbers with particular types of service.
In general, low numbers are reserved for services that users will interact with and high numbers used for things like backbone ports which will not normally be seen.
NET/ROM aliases are used to provide convenient names for services, and are frequently used to provide geographic names for nodes. They should be 6 characters or less.
Software packages
Starting with a fresh, updated Raspberry Pi OS. we need to install ax25-tools
and ax25-apps
.
$ sudo apt-get install ax25-tools ax25-apps
Kernel modules
AX.25 and NET/ROM is included in the Linux kernel packages. AX.25 will load automatically when we configure the TNC, but we need to ensure netrom is loaded.
Add netrom
to /etc/modules
. To load it right away, run:
$ modprobe netrom
TNC
Before we can use the TNC we need to define an AX.25 port for it, and run kissattach
to enable it.
Add the following to /etc/ax25/axports
, replacing N0CALL
with the callsign being used:
tnc N0CALL-15 57600 255 7 NinoTNC
This defines the ax.25 port 'tnc' with its callsign, serial port speed, packet size, window size, and finally a comment describing the port.
The kissattach
program is used to set up communication between a Linux AX.25 interface and a KISS TNC.
In order to assure it runs automatically when the system boots, I'm going to use a systemd unit.
Create a file at /etc/systemd/system/kiss-tnc@.service
containing the following:
# /etc/systemd/system/kiss-tnc@.service
[Unit]
Description=AX25 KISS TNC %I
[Service]
ExecStart=/usr/sbin/kissattach $TNC_TTY %i
ExecStop=pkill -f "kissattach $TNC_TTY %i"
ExecStartPost=/usr/bin/bash -c 'while ! /usr/sbin/kissparms -c 1 -p %i; do sleep 1; done'
TimeoutStopSec=5
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
This is a template unit file that can be used for several TNCs or AXIP tunnels.
To configure an instance for our TNC, first enable it:
$ sudo systemctl enable kiss-tnc@tnc
Then edit it:
$ sudo systemctl edit kiss-tnc@axip
Add the following to the top of the file and then save it:
[Service]
Environment=TNC_TTY=/dev/ttyACM0
$ sudo systemctl start kiss-tnc@tnc
At this point, ip link show
should list an AX.25 port - ax0
as well as four netrom ports - nr0
- nr3
.
We can test that the interface and TNC are working with the 'beacon' command:
$ beacon -s tnc 'This is a test'
If everything is working this will key the radio and send a short message.
If you don't have a radio attached to the TNC you can also check the operation of the beacon
command by running axlisten -cra
in a second terminal window - this will monitor all AX.25 activity on the machine.
NET/ROM port
There are two configuration files for netrom - nrports
and nrbroadcast
.
Much like axports, nrports
assosicates a netrom port name with a callsign, as well as aliases, link quality and a descriptive comment.
Add the folllowing to /etc/ax25/nrports
, again substituting the callsign, and replacing NCALL with a suitable alias for this port.
netrom N0CALL-14 NCALL 236 Linux Switch Port
nrbroadcast
defines a list of AX.25 ports that we're going to run NET/ROM over and that we will use to broadcast routing information.
It also defines parameters which affect descisions about what routes we will accept, and information for other stations about our routes.
I'm not going to describe these in detail just now. If you're joining a NET/ROM network your link partner should be able to advise on the best settings for this file.
Comment out the default lines in /etc/ax25/nrbroadcast
with # characters and add the following:
tnc 5 203 129 1
As with the TNC, we also need to run a command - nrattach
- to enable our NET/ROM interface, and again I'll be using a unit file to make sure this happens on boot.
Create /etc/systemd/system/nrattach@.service
with the following:
[Unit]
Description=AX.25 NET/ROM interface %I
After=network.target
StartLimitInterval=0
[Service]
Type=oneshot
ExecStart=/usr/sbin/nrattach %i
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
This is a template unit so we can use it for more than one netrom port if needed. Specify the netrom port name after an @ when issuing systemctl commands.
$ sudo systemctl daemon-reload
$ sudo systemctl enable nrattach@netrom
$ sudo systmectl start nrattach@netrom
Note: nrattach can be unpredictable if run in parallel. If you're going to use this unit for mutiple NET/ROM ports it will be necessary to ensure the ports are brought up in sequence. This r/systemd post explains how to do this.
netromd
We need to run netromd which will manage the exchange of NET/ROM routing information with other nodes on the network.
It doesn't require any configuration, just another unit file:
Create /etc/systemd/system/netromd.service
:
[Unit]
Description=NET/ROM routing daemon
After=network.target
StartLimitInterval=0
[Service]
Type=simple
Restart=always
RestartSec=5
ExecStart=/usr/sbin/netromd -i
[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl enable netromd
$ sudo systemctl start netromd
Retaining routing information
To preserve bandwith, NET/ROM nodes tend to broadcast their routing information slowly, typically with intervals between 15 and 60 minutes. Because of this it can take a while for a rebooted node to obtain a working routing table.
To help with this, ax25-tools
provides a nodesave
command that can be used to save and reload the NET/ROM routing table when the system is rebooted.
The commands generated by nodesave
will fail if the AX.25 interfaces aren't up, so it's necessary to include After=
lines in the .service file to ensure nodesave.sh is run after relevant services have started.
Create /etc/systemd/system/nodesave.service
:
[Unit]
Description=Persist NET/ROM routing information
After=network.target
After=kiss-tnc@tnc.service
StartLimitInterval=0
[Service]
Type=oneshot
ExecStart=bash -c '[ -x /etc/ax25/nodesave.sh ] && /etc/ax25/nodesave.sh; exit 0'
ExecStop=bash -c '/usr/sbin/nodesave > /etc/ax25/nodesave.sh && chmod 755 /etc/ax25/nodesave.sh'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl enable nodesave
Introduction
The socat
mechanism described in my AX25 over IP post can also be used to connect other AX.25 systems that use KISS together.
A practical use of this is to connect a LinBPQ instance to the Linux AX.25 stack on the system that it's running on. This can be helpful to share a TNC between the two systems, and to allow systems to reach NET/ROM
systems via the other system.
socat
The first thing we need to do is set up the systemd service to manage socat.
I'm assuming BPQ will be running as the linbpq
user as is the case for the packaged
version of LimBPQ distributed by OARC. You may need to adjust the ownership of the /var/ax25/pty/bpq
directory if this is not the case on your system.
Create a file at /etc/systemd/system/kiss-socat-local.service
containing the following:
# /etc/systemd/system/kiss-socat-local.service
[Unit]
Description=Socat interconnect for BPQ
After=network-online.target
Wants=network-online.target
[Service]
WorkingDirectory=/var/ax25
ExecStart=socat -d -d -ly pty,raw,echo=0,link=/var/ax25/pty/bpq/bpq1 pty,raw,echo=0,link=/var/ax25/pty/bpq/bpq2
ExecStartPost=/usr/bin/bash -c 'while ! [ -h /var/ax25/pty/bpq/bpq2 ]; do sleep 1 ; done'
ExecStopPost=rm /var/ax25/pty/bpq/bpq1 /var/ax25/pty/bpq/bpq2
User=linbpq
[Install]
WantedBy=multi-user.target
Create the /var/ax25/pty/bpq
directory, then enable and start the service:
$ sudo mkdir -p /var/ax25/pty/bpq
$ sudo chown linbpq /var/ax25/pty/bpq
$ sudo systemctl daemon-reload
$ sudo systemctl enable kiss-socat-local
$ sudo systemctl start kiss-socat-local
axports
we need an entry in /etc/ax25/axports
- use your callign and a suitable SSID:
local N0CALL-12 115200 255 7 Local connection to LinBPQ
kissattach
The kissattach
program is used to set up communication between Linux's AX.25 stack and LinBPQ
, via the socat
process.
Create a file at /etc/systemd/system/kiss-tnc@.service
containing the following:
# /etc/systemd/system/kiss-tnc@.service
[Unit]
Description=AX25 KISS TNC %I
[Service]
ExecStart=/usr/sbin/kissattach $TNC_TTY %i
ExecStop=pkill -f "kissattach $TNC_TTY %i"
ExecStartPost=/usr/bin/bash -c 'while ! /usr/sbin/kissparms -c 1 -p %i; do sleep 1; done'
TimeoutStopSec=5
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
This is a template unit file that can be used for several TNCs or AXIP tunnels.
To configure an instance for our AXIP tunnel, first enable it:
$ sudo systemctl enable kiss-tnc@local
Then edit it:
$ sudo systemctl edit kiss-tnc@local
Add the following to the top of the file and then save it:
[Unit]
After=kiss-socat-local.service
[Service]
Environment=TNC_TTY=/var/ax25/pty/bpq/bpq2
Restart=on-failure
RestartSec=5s
And then start the service:
$ sudo systemctl start kiss-tnc@local
LinBPQ
To configure the LinBPQ
side of the connection, add the following to your bpq32.cfg file. Adjust the port number to fit with the numbering scheme you are using.
PORT
PORTNUM=2
ID=local
PROTOCOL=KISS
COMPORT=/var/ax25/pty/bpq/bpq1
SPEED=115200
QUALITY=0
MINQUAL=128
MAXFRAME=2
FRACK=4000
RESPTIME=1000
RETRIES=10
PACLEN=236
ENDPORT
The restart LinBPQ
:
$ sudo systemctl restart linbpq
After a few moments you should find you can connect to your LinBPQ
instance from Linux with axcall local
and the callsign BPQ is using.
By increasing the QUALITY
setting and configuring netromd
on the Linux side, NET/ROM
routing information can be exchanged between the two systems.
While AX.25 is typically used over radio links, there are circumstances where it is useful to transport it by other means, such as wired or wireless ethernet, or over established wide area networks.
As with many other protocols, it is fairly simple to encapsulate AX.25 in another network layer, and dencapsulate it when it reaches its destination. For long-distance links it is common to us AX.25 over Internet Protocol, either on the Internet itself or over private networks such as AMPRNet.
In the situation where it is desirable to connect AX.25 systems on a local network, AX.25 over ethernet offers a less complicated solution.
Both Linux and BPQ32 implement AX.25 over Ethernet as 'BPQEther', and it can be used to interoperate between those systems.
On my local network I have a couple of systems running Linux's AX.25 implementation, one of which is connected a radio using a NinoTNC.
On Linux, making use of BPQEther is a simple matter or loading the 'bpqether' module.
One this is loaded, it will create a number of 'bpq' network interfaces, corressponding to the number of ethernet devices on the system. The mappings can be found in /proc/net/bpqether
.
dev ether destination accept from
bpq0 eth0 ff:ff:ff:ff:ff:ff *
To make use of a device, it first needs to be assigned a callsign:
axparms --setcall bpq0 MYCALL-7
optionally, a specific ethernet destiation can be set using bpqparms -d
, otherwise packets will be sent to the network broadcast address, which is adaquate for simple setups with only a small number of systems.
On my Debian based systems I use a the normal network interfaces files to manage bpqether interfaces:
# /etc/network/interfaces.d/bpq0
auto bpq0
iface bpq0 inet manual
up bpqparms bpq0 -d broadcast
up axparms --setcall bpq0 MYCALL-15
up ip link set dev bpq0 up
down ip link set dev bpq0 down
For AX.25 applications to make use of the port, it should also be listed in the axports
file.
#name callsign speed paclen window description
bpq0 MYCALL-15 1000000000 255 7 BPQETHER for eth0
Saw some great films over the last few days that were screening as part of the Bo'ness Hippodrome's "Hippfest" silent film festival.
The Blue Bird (1918) A children's fantasy based on a stage play, with what I assume were at the time innovative filming tecniques.
The Man Who Laughs (1928), based on a Victor Hugo novel with great performances and a main character who's appearance would go on to influence other creative works including DC Comics' Joker.
Shooting Stars (1928) A drama set itself in and around the British film industry of the time, offering as well as a gripping story a glimse into the practicalies of the silent era studio systems.
I've watched silent films at home before but it's a much richer experience to see them in a theatre, especially with the live music performances which had been arranged to accompany the films.
I really like the Hippodrome as a cinema venue, and I'll certainly try to catch the festival again next year.