The legacy packet network frequency known as “Net105” is reference to the lower sideband frequency 14.105 LSB with 300 baud AX/FX.25 tone pairs configured at 1600hz and 1800hz respectively- 1700hz being the center frequency.
Some stations run multiple modes as well as additional packet ’channels’ for BBS interlinks etc, these can be found only on the USB frequency as the multi modes such as VARA, ARDOP and Robust Packet are sideband sensitive and sit at a fixed center frequency of 1500hz.
The USB dial frequency of 14.1022 has been selected to keep backwards compatibility with Net105 as well as provide an additional allocation to handle BBS traffic to help increase throughput.
The equivalent TNC tone pair for Net105 on the USB frequency is 1000hz and 1200hz, 1100hz being the center frequency, the additional AX/FX.25 300 baud allocation pair is at 1900hz and 2100hz (2000hz center frequency).
The multimodes run at a fixed center frequency at 1500hz, with the packet channels described sitting on either side.
You may want to try running QtSoundModem as it helps to visualise the spectrum with a waterfall.
Usually, use of a plain telnet session is sufficient to connect to remote services in BPQ however when the remote service requires a login to occur, sending a prompt to the user and trusting them to input the correct information is unsatisfactory as in some circumstances this can lead to spoofing.
Automating with Expect
The expect tool is used in here to replace the interactive process of logging in with a preset behaviour.
The wrapper script connects to the remote service, in this case- conversd, and sends the command sequence including the callsign of the user to initialize the connection and log the person in with their current callsign connected through the BPQ node.
The callsign itself is provided to the wrapper script by BPQ32 automatically upon connect. The problem with conversd is that it requires a command prefix before the callsign to actually log in.
You will need to ensure that the expect tool is installed on your system, and that the path to ‘expect’ matches in the script provided down below, by default this is /usr/bin/expect.
sudo apt install expect
The wrapper script
gets stdin callsign
spawn -noecho nc IPADDRESS 3600
send "/n $callsign\n"
In the above example, substitute the IPADDRESS with the DNS host name or static IP address of the conversd server you wish to connect to.
You may need to substitute the port number for the one provided to you by the conversd owner. The default is usually port 3600, but it can sometimes differ system to system.
Place this script in a familiar directory, for the sake of example this document will use a sub directory “scripts” within the linbpq home directory.
Set the correct permissions:
chmod 755 /home/bpq/scripts/convwrap
Calling the wrapper script
The wrapper script by itself doesn’t do all of the work. Incoming connections from BPQ have to pass through to a TCP port that is connected to the wrapper script, this is easily achieved with the openbsd-inetd package.
Install ‘openbsd-inetd’ on your system, if using a Raspbian or Debian based install this is accomplished with:
sudo apt install openbsd-inetd
The openbsd-inetd utilizes two configuration files, these are:
Edit the /etc/inetd.conf, insert the following tab-delimited configuration line.
convwrap stream tcp nowait bpq /home/bpq/scripts/convwrap
Note that the references to ‘bpq’ here refer to the user ID that the service will run under. In the example, user ‘bpq’ runs the convwrap script from its own home directory. See Appendix 1 for more information on the inetd.conf syntax.
Edit the /etc/services file and insert a fresh port number for this service, e.g port 63000:
Restart inetd so that it loads the above configuration.
sudo service inetd restart
Insert an APPLICATION line below your existing application definitions, ensure that you select an unused unique application number (the digit after APPLICATION). BPQ has a maximum of 32 application definitions.
APPLICATION 9,WWC,ATTACH 10 127.0.0.1 63000 S,NOCALL-2,ALIAS,255
In the above example:
- ‘9’ refers to application number 9, it is important that you choose an application number between 1-32 that is not already in use.
- WWC is the command alias, a user connected to the BPQ node issues this command to initiate the connection to the wrapper.
- ATTACH is the internal node command that requires a telnet PORTNUM.
- ‘10’ is the telnet PORTNUM associated in bpq32.cfg, it will differ system to system, if your system does not have a telnet port defined, now is the time to do that
- 127.0.0.1 63000 is the host and TCP port number where the wrapper script is provided (see /etc/services from earlier). 127.0.0.1 always refers to ‘localhost’ or ‘self’ in human terms
- ‘S’ is the internal node flag that instructs the node to keep the user connected to the node after disconnecting from the wrapper. This is known as ‘Stay’.
- NOCALL-2 is the optional callsign and SSID you want the wrapper to be reachable via ax25 and NETROM.
- ALIAS is the optional 1-6 character maximum unique ax25 and NETROM alias of the wrapper. Do NOT use the default- make sure you pick one that does not collide with anyone else on the NETROM network.
- ‘255’ is the optional NETROM quality to add the prior optional call sign/alias to the NETROM broadcast, as it is a local and hard-wired service, this can be maximum, 255.
Test the wrapper using the simple telnet program. Connect to the wrapper port, it should show the following:
bpq@pe1rrr:~/scripts $ telnet localhost 63000
Connected to localhost.
Escape character is '^]'.
In order to emulate what BPQ will do, type in your callsign and hit enter.
* Access to channel 0 has been removed from this server.
FYI: No password found.
Try /help mkpass.
conversd @ Rijen_NL Ping-Pong conversd saupp-1.62a
* Type /HELP for help.
* Welcome to RRRWWC Worldwide Converse Server
* Use /help for commands.
*** There are 18 users on 9 channels online.
*** Will try local default channel 3333.
*** You created a new channel 3333.
*** Personal data set from file: Red, Rijen, JO21LO
*** Nickname set from file: Red
From the inetd.conf documentation:
service type protocol wait user server cmdline
The service name. Service names are translated to port numbers by looking them up in the services file (often /etc/services) for TCP and UDP services, or the portmap daemon for RPC services.
The type of socket the service will use. This will be either stream, for connection-oriented protocols, or dgram, for datagram protocols. TCP-based services should always use stream, while UDP-based services should use dgram.
The communication protocol used by the service. This must be a protocol listed in the protocols file (usually found in the same directory as the inetd configuration file). This is usually tcp or udp. RPC services prepend rpc/ to the type.
Whether the service can process multiple requests at one time. This option applies only to dgram sockets. If the service in question can process multiple requests, this should be wait. Otherwise, and for stream sockets, this should be nowait.
The user under which the process should run. Oftentimes this will be root, but if the daemon does not require root privileges, you should consider running it under a less privileged user. Programs which you do not particularly trust, or that you know have security problems are prime candidates to be run under a less privileged user.
The absolute pathname of the daemon to be executed. Internal services are marked by the keyword internal.
The command-line arguments to the daemon. The first argument should be the short name of the program. This is a traditional Unix convention which is normally hidden by the shell.
This is a demonstration of several cool features I have added to a regular packet radio switch, one of which enables access to crucial information that would otherwise have be unobtainable for a vulnerable and isolated radio amateur without Internet (they exist!)
The idea was initially sparked in a chat with a fellow ham Sholto, K7TMG who had expressed the desire to fiddle with websites over packet. At first, I wasn’t too keen on the idea namely because of legal restrictions on the type of information permitted over amateur radio frequencies, however after some thought it occured to me that it would be possible to implement a portal with some precautionary measures in place, but the idea was then shelved.
A couple of weeks passed, and COVID had just begin to spread forcing lockdown/shelter in place in many countries. It was not long after the United Kingdom entered its first major lockdown when a series of packet radio delivered mails arrived from a curious British ham.
I quickly established that this was a much older gentleman that had become isolated and unable to look up information online due to having no Internet or relatives that lived on site that would have been able to. The only people he had any physical contact with were community volunteers dropping off the weekly groceries!
During this time he had resurrected his old “2 meter” ham radio and packet radio modem and linked up to the local packet node through which he established a connection to his local bulletin board, GB7COV, Coventry, in central England.
Over the course of a couple of weeks, numerous requests for up-to-date COVID information as well as prices for replacement motorcycle parts came in to my BBS mailbox here in the Netherlands. It was a little unsettling to see directly how dependent the old and vulnerable are on others in close physical proximity, as he was amidst a world where essentially almost everything is now online-only without so much as a mobile phone.
Still- it was pretty neat that he’d got packet up and running and it was surprising that the node nearest to him was still on the air (thanks to the sysop, Roger- G3ZFR!) after many many years of dwindling usage.
It is important to remember that packet radio was the forerunner of the modern Internet and many hams had packed up shop not long after access to the Internet had become ubiquitous, established affordably in almost every home as just another household utility.
Here follows a video about the interface I had quickly hacked together to work across packet radio at very slow speeds without breaking license rules, utilizing the Lynx browser wrapped within a turn-based-GUI, leveraging the web-to-text conversion system of Lynx together with a custom script converting the hyperlinks to numeric choices from a simple text menu.
The same interface also expanded into additional services such as provisioning text-adventure games over packet radio. Take a look:
QtSoundModem / UZ7HO SoundModem
UZ7HO’s modem has been ported to multi-platform by G8BPQ. The sound-modem is used for interfacing radio with the BPQ switch, in turn providing access to users via RF. Released currently under alpha and beta test as QtSoundModem Software-Terminal Node Controller.
BPQ32 / LinBPQ Packet Network Switch
BPQ switch is the system that connects all of the bits and pieces together: Radio, Computer, Internet, Services and applications.
For simplicity, a simple telnet terminal is sufficient to interface with BPQ32, and BPQ32 also provides a web-browser based terminal and advanced features such as RMS (Winlink Gateway), BBS, APRS and more.
A terminal program. The DOS program Paket 6.2 running in DOSBOX is for demonstrative purposes only, it is not necessary to run this when more modern alternatives exist…
However for this test case, Paket 6.2 is actually the terminal used by the fellow ham mentioned in the introduction. It has been used in this scenario to optimise the appearance of the web portal for the end user.
I mentioned earlier the restrictions on certain types of data over amateur radio links, this is where OpenDNS FamilyShield came into play, and a HTTP proxy server that serves as the filter for requests going to the internet. This is accomplished by setting the proxy to use OpenDNS’s DNS-servers, therefore inheriting their DNS-based safety features.
Another risk reduction measure is the Express Menu- this makes getting information directly pertaining to COVID-19 easier and a simple matter of entering two or three digits. One of the choices available enables one to enter any web address if desired, and those requests are logged, and if necessary- filtered (denied).
On the flip side, retrieving sensitive information across this portal isn’t likely possible due to how there is no method for form submission however for those unaware, all traffic is assumed to be going over the air unprotected and unencrypted, this is due to the legal requirements upon which amateur radio licenses are granted.
All of the tools demonstrated in the video such as Packet Web Portal, Games, Graphs – are all available from my GitHub:
I don’t run the QtSoundModem on the same machine as the node so I use a systemd service script to automatically start up QtSoundModem and put it on a virtual-VNC session that is independent from the physical desktop.
The following systemd scripts call a pair of bash scripts located within the home directory, so that modifications can be done to them without having to reinitialize the systemd service.
sudo apt install realvnc-vnc-server
sudo apt install screen
Note: realvnc is free on the Raspberry Pi, alternatives that may work for other platforms: tightvnc or tigervnc
Description=QtSoundModem Start Script
ExecStart=/usr/bin/screen -S QTSM-Console -d -m /home/pi/bin/startqtsm
Description=Shack Desktop Start Script by PE1RRR
Virtual Virtual VNC?
vvnc for virtual-VNC, yep its a virtual virtual desktop, one that runs independently from the default usually found running as a clone of the desktop monitor display.
This script starts a virtual VNC screen that can be attached from any device such as a smart phone, iPad or other desktop Pi.
vncserver -kill :1
vncserver :1 -geometry 2732x2048
Set permissions to execute:
chmod 755 /home/pi/bin/vvnc
QtSoundModem Start Script
# Launch invisibly
# /home/pi/bin/SM nogui
# Launch with GUI
# Set the display number here. If HDMI connected monitor, this is usually :0
# For VNC sessions, this is determined in the desktop- check it with “echo $DISPLAY” in a shell within the VNC.
/home/pi/bin/QtSoundModem # path to your QtSoundModem binary
Set permissions to execute:
chmod 755 /home/pi/bin/startqtsm
There are a couple of ways of launching QtSoundModem, I prefer to have the GUI to keep and eye on the waterfall and monitor packets etc.. there is an option to start it invisibly in which case- you can opt to use the nogui mode, and remove all references to vvnc.service in the previous scripts as they won’t be needed.
Need only doing once:
sudo systemctl enable qtsm.service
sudo systemctl enable vvnc.service
To Stop/Start manually:
sudo service qtsm start
If the vvnc service is not yet running qtsm’’s service will auto-start it for you. This is due to the “Wants=“ directive in qtsm.service.
Restarting the vvnc service will kill any vnc server running on the display defined in the /home/pi/bin/vvnc file before starting up again.
Displaying the VNC Session
If all has gone well, then QtSoundModem should be displayed on your Virtual VNC screen. That is, assuming you’ve connected a VNC client to it to display it!
The common way to connect to the VNC server is using the address and the display number. 0 (zero) nearly always refers to the hardware-wired display, and the first virtual server after that is :1
Monitoring the Consoles
As these systemd scripts launch with the screen command, this provides a way to keep an eye on the console output without it thrashing the SD Card with continuous writes. To attach to the running screen console, try the following:
If you only have one screen session running then it will re-attach automatically, if not then it will show you a list from which you must provide a string after the -r that can be wildcard-matched either with the process number or the console’s name.
Ideal for Raspbian Buster.
Optional but recommended:
Note in the above example there is a line referencing an application
/usr/bin/screen. If you do not have the
screen package installed, it is highly recommended to do so- screen will create a virtual console for
linbpq, ideal for checking, diagnostics, debug/errors etc.
sudo apt install screen
When the node is running, while logged in as the user defined in the
To attach: screen -r linbpq To detatch, press key combination sequence: Ctrl-a d
I recommend running a script rather than the binary directly so that if you need to add TNC drivers or bind additional devices such as bluetooth TNCs, this would be the ideal place to put them In sequence.
#!/bin/bash # # Edit to reflect the directory location of linBPQ installation cd /home/bpq/node # # Attempt to upgrade (if linbpq.new exists) on next restart mv linbpq.new linbpq ./linbpq
execute and the correct
GROUP permissions on the
runbpq script AND
linbpq binary. This will make it run with the correct user ID if at any point it is launched manually.
sudo chmod +x runbpq chown <userid>:<groupid> runbpq linbpq sudo chmod u+s runbpq linbpq
IMPORTANT: If you drop an upgraded
linbpq into the directory, you should name it
linbpq.new and run the following commands on it to prepare it for when the
linbpq service is next restarted (useful if running a node with a specific scheduled maintenance window).
sudo chmod +x linbpq.new sudo chown <userid>:<groupid> linbpq.new sudo chmod u+s linbpq.new
Starting linbpq from systemd
Create the file
linbpq.service with the following contents:
[Unit] Description=LinBPQ After=network.target [Service] Type=forking WorkingDirectory=/home/bpq/node Restart=always User=bpq Group=bpq ExecStart=/usr/bin/screen -S linbpq -d -m /home/bpq/node/runbpq #ExecStart=/bin/bash /home/bpq/node/runbpq SyslogIdentifier=LinBPQ [Install] WantedBy=multi-user.target
ExecStart path to reflect the location of
runbpq on your system.
linbpq.service into the
sudo mv ./linbpq.service /etc/systemd/system/ cd /etc/systemd/system/
sudo systemctl daemon-reload sudo systemctl enable linbpq.service
Which does this:
Created symlink /etc/systemd/system/multi-user.target.wants/linbpq.service → /etc/systemd/system/linbpq.service.
And that should be it. LinBPQ will now start from boot, and you have prepared a system to assist with future upgrades of the node binary.
You can check your systemd startup sequence status issuing:
sudo systemctl status
Got a Raspberry Pi and want to get back into Packet Radio?
The LinBPQ-RTG has been moved to a GitHub repository, meaning keep it up-to-date is much easier. To download, install ‘git’ on your system and use the following command to copy the repository to your system:
git clone https://github.com/pe1rrr/linbpq_rtg
This is a complete packet radio setup for amateur radio use. The repository has binaries included for the Raspberry Pi providing the full node network stack, QtSoundModem and QtTermTCP.
The repository contains documentation and configuration pretty much ready to go, only a few things need to be edited to set your callsign, file paths and a couple of parameters such as grid square locator, GPS coordinates and APRS-IS password.
Please note this software is in Beta, it is recommended that you run all three update scripts before starting, and most importantly, read the README.md – also viewable on https://github.com/pe1rrr/linbpq_rtg
Recommended system requirements: Raspberry Pi4 if running the provided QtSoundModem soundmodem. If not using the soundmodem, serial port based TNCs can be used on a Pi Model B / Pi Zero as the performance overhead is much lower. Raspberry Pi Model 3’s have issues with ALSA driver (see: https://bugs.launchpad.net/raspbian/+bug/1819560) although a workaround has been included in the repository, see qtsm_rpi3 file.
If you wish to compile the source code yourself, download the latest archive from G8BPQ’s website/repository here. If using a 64bit OS, you must first install x86 32bit compatibility libraries before building. A binary compiled without these may execute but it will send corrupted frames, so be careful.
Red – PE1RRR
The update scripts provided can be easily modified to download the binaries for x86 32bit Linux.
Open them in a text editor and adjust the filename= parameter.
The filename downloaded by the scripts should be changed from ‘pilinbpq’ to ‘linbpq’. The same procedure should be employed for qtsm and qtterm update scripts- just remove the ‘pi’.
If running a 64bit OS you will need to install the 32bit compatibility libraries. For Ubuntu and Debian, this is accomplished with:
apt-get install ia32-libs
For Windows users, the configuration files are compatible with the Win32 build of BPQ32 available from G8BPQ’s website here.
Be aware the configuration here is for the latest Beta so after installing the Win32 package, also download the latest beta DLL. As this package is aimed at Raspbian Linux for the Raspberry Pi it is a little out of scope to provide details for the Windows platform.
UPDATE – Foreword: The easiest way to exchange mail between BPQ and JNOS would be to simply create a AXUDP link between BPQ and JNOS and then use NETROM connectivity to do regular AX25 connections over the link. The document below was composed before this realisation.
This foreword is here as a heads up that using Telnet method is really the longest route around the problem, and is really not recommended.
Internally Forwarding Mail to BPQ
Create a new user with BBS flags for your JNOS instance within the BPQ User Management Area.
For this account, do not use the callsign of the JNOS instance, instead use a descriptive alias. This avoids a problem with callsign collision which will usually cause JNOS to refuse to work. In my example, I will refer to this USER as RRRNOS on the BPQ side.
The HROUTE of
RRRNOS.PE1RRR.NLD.EURO, as configured in the mailbox settings for JNOS.
All mail for
RRRNOS arrives first at
PE1RRR.NLD.EURO and is queued for forwarding to
In turn, we also will refer to the BPQMail instance in the JNOS configuration as MATRIX, rather than the callsign.
IMPORTANT: The passwords for BPQ telnet sessions are NOT defined in the BPQMail User account, but instead in the bpq32.cfg node configuration file under the
TELNET port declaration. See BPQ Telnet Server Documentation.
matrix 0023 P telnet <bpq node address> <bpq fbbport> cronly .<bpq port defined telnet userid> .<password> * 0 .BBS * 0 <list of areas to forward>
FBBPORT is often misunderstood as a direct connection to the BBS- when it is not. The port opens a connection to only the node which is why we must issue an extra command:
FBB sysops frequently get this wrong and wonder why their telnet forwarding to a BPQMail instance doesn't work.
It is necessary to provide BPQMail with an account on JNOS with which to log in and access BBS functions. This is possible by adding an account with the necessary privileges set.
JNOS won’t allow the use of an invalid callsign for a login user ID by default, to do so would require recompiling the JNOS source with one of the config.h “defines” changed (it is easy to do, but not recommended).
A workaround, if forwarding downstream to yourself– is to just use your own callsign for the login, as it would be coming from your own upstream BPQMail BBS anyway.
Permissions needed (if not using your own sysop login):
FTPUSERS PERMISSIONS reference sheet, sum up the permission level as such:
- Summed together:
FTPUSERS PERMISSIONS The following is a list of the user permission values allowed in FTPUSERS file. Name value hex value comments FTP_READ 1 0x1 /* Read files */ FTP_CREATE 2 0x2 /* Create new files */ FTP_WRITE 4 0x4 /* Overwrite or delete existing files */ AX25_CMD 8 0x8 /* AX.25 gateway operation allowed */ TELNET_CMD 16 0x10 /* Telnet gateway operation allowed */ NETROM_CMD 32 0x20 /* NET/ROM gateway operation allowed */ SYSOP_CMD 64 0x40 /* Remote sysop access allowed */ EXCLUDED_CMD 128 0x80 /* This user is banned from the BBS */ PPP_ACCESS_PRIV 256 0x100 /* bit for PPP connection */ PPP_PWD_LOOKUP 512 0x200 /* Priv bit for peerID/pass lookup */ NO_SENDCMD 1024 0x400 /* Disallow send command */ NO_READCMD 2048 0x800 /* Disallow read command */ NO_3PARTY 4096 0x1000 /* Disallow third-party mail */ IS_BBS 8192 0x2000 /* This user is a bbs */ IS_EXPERT 16384 0x4000 /* This user is an expert */ NO_CONVERS 32768 0x8000 /* Disallow convers command */ NO_ESCAPE 65536 0x10000 /* Default is no escape char */ NO_LISTS 131072 0x20000 /* No lists displayed from mailbox */ NO_LINKEDTO 262144 0x40000 /* Disable '*** linked to' */ NO_LASTREAD 524288 0X80000 /* Ignore lastread in <area>.usr (shared accts)*/ NO-FBBCMP 1048576 0x100000 /* Avoid FBB compression */ XG_ALLOWED 2097152 0X200000 /* Allow XG (dynip route) cmd */
ftpusers file and append:
<callsign> <password> /jnos/public 24576
Note: If this BBS is also a regular user, give them AX and netrom permissions too (add 8 + 32 to the final sum).
Configuring BPQ Forwarding
The BPQ User created with the BBS flag (
RRRNOS in this example) should be visible in the
Forwarding Management Area of BPQ as one of the callsigns in the list.
RRRNOS user and then set the fields with the following information, if not explicitly mentioned, the fields are to be left empty.
ATTACH 10 C <jnos host/ip> <jnos port> TELNET <jnos userid> <jnos password>
Hierarchical Routes (Flood Bulls)
AF AS OC EURO NOAM SOAM CEAM WW
HR (Personals and Directed Bulls)
Enabled Checkbox/Flags (all not explicitly mentioned should be disabled)
- Enable Forwarding [
ON] Interval [
- FBB Blocked [
ON] Max Block [
- Send new messages without waiting for poll timer [
- Allow Binary [
- Use B2 Protocol [
Update to finish.
Check and Test
Open a new terminal an go to your BPQ directory, open the log file using the tail command, this will open the log file and checks the file for new data is written to it every 0.1 seconds.
tail -f -s 0.1 logLatest_BBS.txt
From the BPQ
Forwarding Area, select the BBS account and click
fwd <callsign> now from the BPQ mail prompt.
Watch the log file for errors.
If all goes well this is what you should see:
200213 16:31:41 |RRRNOS Incoming Connect from RRRNOS 200213 16:31:41 >RRRNOS [BPQ-22.214.171.124-B2FWIHJM$] 200213 16:31:41 >RRRNOS 0 messages to fwd to RRRNOS 200213 16:31:41 >RRRNOS PE1RRR BBS> 200213 16:31:41 <RRRNOS [JNOS-2.0m-B2FHIM$] 200213 16:31:42 <RRRNOS FF 200213 16:31:42 >RRRNOS FQ 200213 16:31:42 |RRRNOS RRRNOS Disconnected
To test from the other direction, log into JNOS sysop console and issue:
Note: In the examples below. ‘MATRIX’ is the arbitrary name I have given to the BPQ mailbox in JNOS, it just so happens to also be the BPQ mailbox’s NETROM alias but that is not important at all as this is a telnet session, it is just for practicality.
mbox kick <bpq bbs name defined in forward.bbs> e.g. mbox kick MATRIX
Note: when calling
mbox kick, use
upper case for the
callsign if there is no local mail to actually forward. This initiates a reverse forward. If you don’t use this method, and you have no mail to forward, it won’t try and connect, and as such you won’t see diddly squat happening in the log file.