From 5ed346ad4ca1f50d98f740c0b085d55c730a14b1 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 11 May 2026 07:25:20 -0700 Subject: [PATCH 01/64] reticulum - Initial work on integrating Reticulum into EmComm Tools --- overlay/etc/skel/.bash_profile | 2 + .../reticulum/ttp-reticulum-setup-notes.md | 102 ++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 overlay/etc/skel/Desktop/offline/reticulum/ttp-reticulum-setup-notes.md diff --git a/overlay/etc/skel/.bash_profile b/overlay/etc/skel/.bash_profile index 8b31d4d..58c1ba2 100644 --- a/overlay/etc/skel/.bash_profile +++ b/overlay/etc/skel/.bash_profile @@ -3,6 +3,8 @@ # Updated : 16 April 2026 # Description : bash profile +export PATH="$HOME/.local/bin:$PATH" + # All user accounts should be in the 'et-data' group to allow data sharing with # EmComm Tools. A umask of 002 is required to allow users and the system to # read and write shared data files. diff --git a/overlay/etc/skel/Desktop/offline/reticulum/ttp-reticulum-setup-notes.md b/overlay/etc/skel/Desktop/offline/reticulum/ttp-reticulum-setup-notes.md new file mode 100644 index 0000000..b291606 --- /dev/null +++ b/overlay/etc/skel/Desktop/offline/reticulum/ttp-reticulum-setup-notes.md @@ -0,0 +1,102 @@ +--- +title: Reticulum Setup Notes +date: 2026-02-13 +updated: 2026-05-11 +author: [The Tech Prepper] +categories: [reticulum] +tags: [reticulum] +--- + +The following are my personal notes while workthrough an initial evaluation +of Reticulum for use over packet radio. + +1. Install Python 3. +``` +sudo apt install \ + python3 \ + python3-pip \ + -y +``` + +2. Add `~/.local/bin` to your PATH. + +3. Install Reticulum as a non-priveleged user. +``` +python3 -m pip install --user rns +``` + +4. Verify that the Reticulum daemon is installed correctly. +``` +which rnsd +``` + +4. Start Reticulum. This will start the service and create an initial + configuration file under `.reticulum/config`. +``` +rnsd +``` + + +5. Stop the service with `+C`. + +6. Edit `~/.reticulum/config` and enable the AX.25 interface by + adding the KISS section below. +``` +[interfaces] + + # This interface enables communication with other + # link-local Reticulum nodes over UDP. It does not + # need any functional IP infrastructure like routers + # or DHCP servers, but will require that at least link- + # local IPv6 is enabled in your operating system, which + # should be enabled by default in almost any OS. See + # the Reticulum Manual for more configuration options. + + # Default local LAN interface (keep this enabled for testing) + [[Default Interface]] + type = AutoInterface + enabled = No + + [[Packet Radio AX25 KISS]] + type = AX25KISSInterface + enabled = Yes + + callsign = KT7RUN + ssid = 2 + + port = /tmp/kisstnc + mtu = 256 +``` + +7. Start Dire Wolf. In EmComm Tools, run `et-mode` and select + `bbs-client`. + +8. In another terminal, start Reticulum. +``` +rnsd +``` + +If successful, you should see something like the following: +``` +$ rnsd +[2026-02-14 12:59:02] [Notice] Serial port /tmp/kisstnc is now open +[2026-02-14 12:59:02] [Notice] Configuring KISS interface parameters... +[2026-02-14 12:59:02] [Notice] KISS interface configured +[2026-02-14 12:59:02] [Notice] Started rnsd version 1.1.3 +``` + +## Install a Message App + +1. Install NomadNet. +``` +python3 -m pip install --user nomadnet +``` + +2. Start NomadNet. +``` +nomadnet +``` + +## Add Identity + +TODO From 2947e08865a47101fefd1659d6e5c9a446d6fb21 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 11 May 2026 07:34:41 -0700 Subject: [PATCH 02/64] reticulum - Added the Reticulum Primer by Michael Faragher for offline reading. --- scripts/install-offline-lib.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/install-offline-lib.json b/scripts/install-offline-lib.json index 606ff6f..871d626 100644 --- a/scripts/install-offline-lib.json +++ b/scripts/install-offline-lib.json @@ -38,5 +38,10 @@ "url": "https://www.swpc.noaa.gov/sites/default/files/images/NOAAscales.pdf", "file": "NOAAscales.pdf", "dir": "space-weather" + }, + { + "url": "https://reticulum.betweentheborders.com/primer.pdf", + "file": "primer.pdf", + "dir": "reticulum" } ] From b18f6a4dbc6d2a4e2298d0276d17964b210d8df9 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 11 May 2026 09:29:16 -0700 Subject: [PATCH 03/64] reticulum - Initial work to install Reticulum and Nomad for use be a local user. --- scripts/install-reticulum.sh | 32 ++++++++++++++++++++++++++++++++ scripts/install.sh | 5 ++++- tests/test-nomadnet.sh | 7 +++++++ tests/test-rnsd.sh | 7 +++++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100755 scripts/install-reticulum.sh create mode 100755 tests/test-nomadnet.sh create mode 100755 tests/test-rnsd.sh diff --git a/scripts/install-reticulum.sh b/scripts/install-reticulum.sh new file mode 100755 index 0000000..0724551 --- /dev/null +++ b/scripts/install-reticulum.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Author : Gaston Gonzalez +# Date : 13 February 2026 +# Updated : 11 May 2026 +# Purpose : Install Reticulum + +# Version pin Reticulum and Nomadnet as we want to favor stability +# above all other concerns (security, features, etc.). +RNS_VERSION=1.2.5 +NOMADNET_VERSION=0.9.8 + +et-log "Installing Python3..." +apt install \ + python3 \ + python3-pip \ + -y + +et-log "Downloading rns ${RNS_VERSION} for offline install..." +python3 -m pip download -d wheelhouse rns==${RNS_VERSION} + +et-log "Downloading nomadnet ${NOMADNET_VERSION} for offline install..." +python3 -m pip download -d wheelhouse nomadnet==${NOMADNET_VERSION} + +et-log "Installing Reticulum and Nomadnet for single user use..." +PYTHONUSERBASE=/etc/skel/.local \ + python3 -m pip install --user \ + --no-index --find-links=wheelhouse \ + rns==${RNS_VERSION} \ + nomadnet==${NOMADNET_VERSION} + +et-log "Removing wheelhouse to save space..." +[[ -e wheelhouse ]] && rm -vrf wheelhouse diff --git a/scripts/install.sh b/scripts/install.sh index e09c6fb..89fa035 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 16 March 2024 -# Updated : 7 May 2026 +# Updated : 11 May 2026 # Purpose : Main installer for EmComm Tools Community (ETC) . ./env.sh @@ -119,5 +119,8 @@ exitIfNotRoot # Security Patches ./patch-copy-fail.sh +# Install Reticulum and NomadNet +./install-reticulum.sh + # Debrand Ubuntu ./debrand.sh diff --git a/tests/test-nomadnet.sh b/tests/test-nomadnet.sh new file mode 100755 index 0000000..68daf78 --- /dev/null +++ b/tests/test-nomadnet.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# Author : Gaston Gonzalez +# Date : 11 April 2025 +# Purpose : Test NomadNet installation + +OUT=$(PYTHONUSERBASE=/etc/skel/.local /etc/skel/.local/bin/nomadnet --version) +exit $? diff --git a/tests/test-rnsd.sh b/tests/test-rnsd.sh new file mode 100755 index 0000000..c762f5b --- /dev/null +++ b/tests/test-rnsd.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# Author : Gaston Gonzalez +# Date : 11 April 2025 +# Purpose : Test Reticulum installation + +OUT=$(PYTHONUSERBASE=/etc/skel/.local /etc/skel/.local/bin/rnsd --version) +exit $? From 240213cab4170cf6d58435473019268dc91e161e Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 11 May 2026 09:34:11 -0700 Subject: [PATCH 04/64] todo - Add near term to-do items --- TODO.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..36a2ba3 --- /dev/null +++ b/TODO.md @@ -0,0 +1,17 @@ +# To-Do + +* [ ] Add Reticulum + * [ ] Add .reticulum/config with template support + * [ ] Add rnsd systemd service (user) + * [ ] Add nomadnet systemd service (user) + * [ ] Add et-mode with encryption warning +* [ ] et-mail +* [ ] et-debug +* [ ] et-index +* [ ] See email: "Found on Discord GPS issue" + * [ ] Fix dial frequency + * [ ] Update rmslist.csv (et-data-winlink) +* Add radio support + * [ ] TX500MP + LINK500MP + * [ ] IC-7300 MkII +* [ ] Thunderbird (Optional) From e612fac64b83988aaa2e38b24098f73c3cc3880d Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 11 May 2026 09:39:46 -0700 Subject: [PATCH 05/64] reticulum - Initial Reticulum configuration with AX.25 support based on my original proof-of-concept from rnsd version 1.1.3. --- overlay/etc/skel/.reticulum/config | 128 +++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 overlay/etc/skel/.reticulum/config diff --git a/overlay/etc/skel/.reticulum/config b/overlay/etc/skel/.reticulum/config new file mode 100644 index 0000000..4c55d13 --- /dev/null +++ b/overlay/etc/skel/.reticulum/config @@ -0,0 +1,128 @@ +# This is the default Reticulum config file. +# You should probably edit it to include any additional, +# interfaces and settings you might need. + +# Only the most basic options are included in this default +# configuration. To see a more verbose, and much longer, +# configuration example, you can run the command: +# rnsd --exampleconfig + + +[reticulum] + + # If you enable Transport, your system will route traffic + # for other peers, pass announces and serve path requests. + # This should only be done for systems that are suited to + # act as transport nodes, ie. if they are stationary and + # always-on. This directive is optional and can be removed + # for brevity. + + enable_transport = False + + + # By default, the first program to launch the Reticulum + # Network Stack will create a shared instance, that other + # programs can communicate with. Only the shared instance + # opens all the configured interfaces directly, and other + # local programs communicate with the shared instance over + # a local socket. This is completely transparent to the + # user, and should generally be turned on. This directive + # is optional and can be removed for brevity. + + share_instance = Yes + + + # If you want to run multiple *different* shared instances + # on the same system, you will need to specify different + # instance names for each. On platforms supporting domain + # sockets, this can be done with the instance_name option: + + instance_name = default + + +# Some platforms don't support domain sockets, and if that +# is the case, you can isolate different instances by +# specifying a unique set of ports for each: + +# shared_instance_port = 37428 +# instance_control_port = 37429 + + +# If you want to explicitly use TCP for shared instance +# communication, instead of domain sockets, this is also +# possible, by using the following option: + +# shared_instance_type = tcp + + +# You can configure whether Reticulum should discover +# available interfaces from other Transport Instances over +# the network. If this option is enabled, Reticulum will +# collect interface information discovered from the network. + +# discover_interfaces = No + + +# You can configure Reticulum to panic and forcibly close +# if an unrecoverable interface error occurs, such as the +# hardware device for an interface disappearing. This is +# an optional directive, and can be left out for brevity. +# This behaviour is disabled by default. + +# panic_on_interface_error = No + + +# If you're connecting to a large external network, you +# can use one or more external blackhole list to block +# spammy and excessive announces onto your network. This +# funtionality is especially useful if you're hosting public +# entrypoints or gateways. The list source below provides a +# functional example, but better, more timely maintained +# lists probably exist in the community. + +# blackhole_sources = 521c87a83afb8f29e4455e77930b973b + + +[logging] + # Valid log levels are 0 through 7: + # 0: Log only critical information + # 1: Log errors and lower log levels + # 2: Log warnings and lower log levels + # 3: Log notices and lower log levels + # 4: Log info and lower (this is the default) + # 5: Verbose logging + # 6: Debug logging + # 7: Extreme logging + + loglevel = 4 + + +# The interfaces section defines the physical and virtual +# interfaces Reticulum will use to communicate on. This +# section will contain examples for a variety of interface +# types. You can modify these or use them as a basis for +# your own config, or simply remove the unused ones. + +[interfaces] + + # This interface enables communication with other + # link-local Reticulum nodes over UDP. It does not + # need any functional IP infrastructure like routers + # or DHCP servers, but will require that at least link- + # local IPv6 is enabled in your operating system, which + # should be enabled by default in almost any OS. See + # the Reticulum Manual for more configuration options. + + [[Default Interface]] + type = AutoInterface + enabled = No + + [[Packet Radio AX25 KISS]] + type = AX25KISSInterface + enabled = Yes + + callsign = {{ET_CALLSIGN}} + ssid = 1 + + port = /tmp/kisstnc + mtu = 256 From c14a9c155e226cea144f1e4c803c9306f121fe34 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 12 May 2026 07:40:35 -0700 Subject: [PATCH 06/64] reticulum - Initial work on et-reticulum wrapper script --- overlay/opt/emcomm-tools/bin/et-reticulum | 134 ++++++++++++++++++ .../template.d/reticulum/config.ax25.1200 | 128 +++++++++++++++++ .../conf/template.d/reticulum/config.ax25.300 | 128 +++++++++++++++++ 3 files changed, 390 insertions(+) create mode 100755 overlay/opt/emcomm-tools/bin/et-reticulum create mode 100644 overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.1200 create mode 100644 overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.300 diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum new file mode 100755 index 0000000..f535731 --- /dev/null +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -0,0 +1,134 @@ +#!/bin/bash +# +# Author : Gaston Gonzalez +# Date : 12 May 2026 +# Purpose : Wrapper script for starting Reticulum with PnP support +# +# Preconditions: +# 1. Supported radio and audio interface are connected and properly detected +# +# Postconditions: +# 1. Reticulum configuration updated +# 2. Dire Wolf started +# 3. Reticulum started +. /opt/emcomm-tools/bin/et-common + +APP="Reticulum" +RETICULUM_CONF_FILE="${HOME}/.reticulum/config" + +usage() { + echo "usage: $(basename $0) " + echo " " + echo " start - Start ${APP} in selected mode" + echo " update-config - Update configuration for selected mode" + echo "" + echo " " + echo " 1200 - Run with AX.25 interface over VHF/UHF (1200 baud)" + echo " 300 - Run with AX.25 interface over HF (300 baud)" +} + +if [ $# -ne 2 ]; then + usage + exit 1 +fi + +MODE=$2 +case "${MODE}" in + 1200) + RETICULUM_TEMPLATE_CONF_FILE="${ET_HOME}/conf/template.d/reticulum/config.ax25.1200" + RETICULUM_PACKET_INTERFACE_SERVICE=et-service-direwolf-simple + ;; + 300) + RETICULUM_TEMPLATE_CONF_FILE="${ET_HOME}/conf/template.d/reticulum/config.ax25.300" + RETICULUM_PACKET_INTERFACE_SERVICE=et-service-direwolf-300 + ;; + *) + et-log "Can't start ${APP}. Mode '${MODE}' not supported" + usage + exit 1 + ;; +esac + +if [[ ! -e "${RETICULUM_TEMPLATE_CONF_FILE}" ]]; then + et-log "${RETICULUM_TEMPLATE_CONF_FILE} does not exist. Exiting." + notify-user "Config file does not exist. Can't start Reticulum." + exit 1 +fi + +start() { + update_config + + if [[ $? -eq 0 ]]; then + + systemctl is-active --quiet ${RETICULUM_PACKET_INTERFACE_SERVICE} + if [[ $? -ne 0 ]]; then + et-log "Can't start ${APP}. direwolf not running. Ensure radio is selected." + notify-user "Can't start ${APP}. direwolf not running." + exit 1 + fi + + CMD="rnsd" + et-log "Starting ${APP} with: '${CMD}'" + echo + ${CMD} + else + et-log "Error updating configuration. Can't start ${APP}" + exit 1 + fi +} + + +update_config () { + + et-log "Attempting to start ${APP} in mode: '${MODE}'" + + [[ -z "$ET_USER_CONFIG" ]] && ET_USER_CONFIG="${HOME}/.config/emcomm-tools/user.json" + + CALLSIGN=$(cat ${ET_USER_CONFIG} | jq -r .callsign) + + if [[ "${CALLSIGN}" = "N0CALL" ]]; then + notify_user "Can't ${APP}. No callsign set. Run: et-user." + exit 1 + fi + + # 1. Check if the audio symlink was created by the udev rules + if [[ -e /dev/et-audio ]]; then + + # Check that this device was properly tagged with the ET_AUDIO env variable with a udev rule + APLAY_OUT=$(arecord -l | grep ET_AUDIO) + if [[ $? -eq 0 ]]; then + + # Configure ALSA settings for sound card + /opt/emcomm-tools/bin/et-audio update-config + + else + et-log "No ET_AUDIO device detected." + notify-user "Can't start ${APP}. No ET_AUDIO device detected." + exit 1 + fi + else + et-log "No ET_AUDIO device plugged in." + notify-user "Can't start ${APP}. No supported audio device plugged in." + exit 1 + fi + + et-log "Creating '${RETICULUM_CONF_FILE}' from template '${RETICULUM_TEMPLATE_CONF_FILE}'" + cp ${RETICULUM_TEMPLATE_CONF_FILE} ${RETICULUM_CONF_FILE} + + # Update callsign + sed -i "s|{{ET_CALLSIGN}}|${CALLSIGN}|g" ${RETICULUM_CONF_FILE} +} + +case $1 in + start) + start + ;; + update-config) + update_config + ;; + *) + echo "Invalid command." + usage + exit 1 + ;; +esac diff --git a/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.1200 b/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.1200 new file mode 100644 index 0000000..4c55d13 --- /dev/null +++ b/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.1200 @@ -0,0 +1,128 @@ +# This is the default Reticulum config file. +# You should probably edit it to include any additional, +# interfaces and settings you might need. + +# Only the most basic options are included in this default +# configuration. To see a more verbose, and much longer, +# configuration example, you can run the command: +# rnsd --exampleconfig + + +[reticulum] + + # If you enable Transport, your system will route traffic + # for other peers, pass announces and serve path requests. + # This should only be done for systems that are suited to + # act as transport nodes, ie. if they are stationary and + # always-on. This directive is optional and can be removed + # for brevity. + + enable_transport = False + + + # By default, the first program to launch the Reticulum + # Network Stack will create a shared instance, that other + # programs can communicate with. Only the shared instance + # opens all the configured interfaces directly, and other + # local programs communicate with the shared instance over + # a local socket. This is completely transparent to the + # user, and should generally be turned on. This directive + # is optional and can be removed for brevity. + + share_instance = Yes + + + # If you want to run multiple *different* shared instances + # on the same system, you will need to specify different + # instance names for each. On platforms supporting domain + # sockets, this can be done with the instance_name option: + + instance_name = default + + +# Some platforms don't support domain sockets, and if that +# is the case, you can isolate different instances by +# specifying a unique set of ports for each: + +# shared_instance_port = 37428 +# instance_control_port = 37429 + + +# If you want to explicitly use TCP for shared instance +# communication, instead of domain sockets, this is also +# possible, by using the following option: + +# shared_instance_type = tcp + + +# You can configure whether Reticulum should discover +# available interfaces from other Transport Instances over +# the network. If this option is enabled, Reticulum will +# collect interface information discovered from the network. + +# discover_interfaces = No + + +# You can configure Reticulum to panic and forcibly close +# if an unrecoverable interface error occurs, such as the +# hardware device for an interface disappearing. This is +# an optional directive, and can be left out for brevity. +# This behaviour is disabled by default. + +# panic_on_interface_error = No + + +# If you're connecting to a large external network, you +# can use one or more external blackhole list to block +# spammy and excessive announces onto your network. This +# funtionality is especially useful if you're hosting public +# entrypoints or gateways. The list source below provides a +# functional example, but better, more timely maintained +# lists probably exist in the community. + +# blackhole_sources = 521c87a83afb8f29e4455e77930b973b + + +[logging] + # Valid log levels are 0 through 7: + # 0: Log only critical information + # 1: Log errors and lower log levels + # 2: Log warnings and lower log levels + # 3: Log notices and lower log levels + # 4: Log info and lower (this is the default) + # 5: Verbose logging + # 6: Debug logging + # 7: Extreme logging + + loglevel = 4 + + +# The interfaces section defines the physical and virtual +# interfaces Reticulum will use to communicate on. This +# section will contain examples for a variety of interface +# types. You can modify these or use them as a basis for +# your own config, or simply remove the unused ones. + +[interfaces] + + # This interface enables communication with other + # link-local Reticulum nodes over UDP. It does not + # need any functional IP infrastructure like routers + # or DHCP servers, but will require that at least link- + # local IPv6 is enabled in your operating system, which + # should be enabled by default in almost any OS. See + # the Reticulum Manual for more configuration options. + + [[Default Interface]] + type = AutoInterface + enabled = No + + [[Packet Radio AX25 KISS]] + type = AX25KISSInterface + enabled = Yes + + callsign = {{ET_CALLSIGN}} + ssid = 1 + + port = /tmp/kisstnc + mtu = 256 diff --git a/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.300 b/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.300 new file mode 100644 index 0000000..4c55d13 --- /dev/null +++ b/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.300 @@ -0,0 +1,128 @@ +# This is the default Reticulum config file. +# You should probably edit it to include any additional, +# interfaces and settings you might need. + +# Only the most basic options are included in this default +# configuration. To see a more verbose, and much longer, +# configuration example, you can run the command: +# rnsd --exampleconfig + + +[reticulum] + + # If you enable Transport, your system will route traffic + # for other peers, pass announces and serve path requests. + # This should only be done for systems that are suited to + # act as transport nodes, ie. if they are stationary and + # always-on. This directive is optional and can be removed + # for brevity. + + enable_transport = False + + + # By default, the first program to launch the Reticulum + # Network Stack will create a shared instance, that other + # programs can communicate with. Only the shared instance + # opens all the configured interfaces directly, and other + # local programs communicate with the shared instance over + # a local socket. This is completely transparent to the + # user, and should generally be turned on. This directive + # is optional and can be removed for brevity. + + share_instance = Yes + + + # If you want to run multiple *different* shared instances + # on the same system, you will need to specify different + # instance names for each. On platforms supporting domain + # sockets, this can be done with the instance_name option: + + instance_name = default + + +# Some platforms don't support domain sockets, and if that +# is the case, you can isolate different instances by +# specifying a unique set of ports for each: + +# shared_instance_port = 37428 +# instance_control_port = 37429 + + +# If you want to explicitly use TCP for shared instance +# communication, instead of domain sockets, this is also +# possible, by using the following option: + +# shared_instance_type = tcp + + +# You can configure whether Reticulum should discover +# available interfaces from other Transport Instances over +# the network. If this option is enabled, Reticulum will +# collect interface information discovered from the network. + +# discover_interfaces = No + + +# You can configure Reticulum to panic and forcibly close +# if an unrecoverable interface error occurs, such as the +# hardware device for an interface disappearing. This is +# an optional directive, and can be left out for brevity. +# This behaviour is disabled by default. + +# panic_on_interface_error = No + + +# If you're connecting to a large external network, you +# can use one or more external blackhole list to block +# spammy and excessive announces onto your network. This +# funtionality is especially useful if you're hosting public +# entrypoints or gateways. The list source below provides a +# functional example, but better, more timely maintained +# lists probably exist in the community. + +# blackhole_sources = 521c87a83afb8f29e4455e77930b973b + + +[logging] + # Valid log levels are 0 through 7: + # 0: Log only critical information + # 1: Log errors and lower log levels + # 2: Log warnings and lower log levels + # 3: Log notices and lower log levels + # 4: Log info and lower (this is the default) + # 5: Verbose logging + # 6: Debug logging + # 7: Extreme logging + + loglevel = 4 + + +# The interfaces section defines the physical and virtual +# interfaces Reticulum will use to communicate on. This +# section will contain examples for a variety of interface +# types. You can modify these or use them as a basis for +# your own config, or simply remove the unused ones. + +[interfaces] + + # This interface enables communication with other + # link-local Reticulum nodes over UDP. It does not + # need any functional IP infrastructure like routers + # or DHCP servers, but will require that at least link- + # local IPv6 is enabled in your operating system, which + # should be enabled by default in almost any OS. See + # the Reticulum Manual for more configuration options. + + [[Default Interface]] + type = AutoInterface + enabled = No + + [[Packet Radio AX25 KISS]] + type = AX25KISSInterface + enabled = Yes + + callsign = {{ET_CALLSIGN}} + ssid = 1 + + port = /tmp/kisstnc + mtu = 256 From 9b65d807373fbbfa9b7bba2af25fcb83c7dad2ad Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 12 May 2026 07:49:56 -0700 Subject: [PATCH 07/64] reticulum - Start the appropriate direwolf systemd service based on the desired packet mode --- overlay/opt/emcomm-tools/bin/et-reticulum | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum index f535731..9ffbe10 100755 --- a/overlay/opt/emcomm-tools/bin/et-reticulum +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -62,9 +62,7 @@ start() { systemctl is-active --quiet ${RETICULUM_PACKET_INTERFACE_SERVICE} if [[ $? -ne 0 ]]; then - et-log "Can't start ${APP}. direwolf not running. Ensure radio is selected." - notify-user "Can't start ${APP}. direwolf not running." - exit 1 + start_and_wait_for_service ${RETICULUM_PACKET_INTERFACE_SERVICE} fi CMD="rnsd" From 350539025f8180002405b328684f7ac3cc14e675 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 12 May 2026 07:52:21 -0700 Subject: [PATCH 08/64] reticulum - Updated TODO and REGRESSION docs --- REGRESSION.md | 5 +++-- TODO.md | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/REGRESSION.md b/REGRESSION.md index fdc731b..c02fd8d 100644 --- a/REGRESSION.md +++ b/REGRESSION.md @@ -1,7 +1,7 @@ # ETC Regression Tests -- **Build**: ETC R7 Build 1 -- **Date**: 16 April 2026 +- **Build**: ETC R7 Build 3 +- **Date**: 12 May 2026 ## Desktop/Launcher Icons @@ -83,6 +83,7 @@ * [ ] Select RMS gateway => VFO updated * [ ] Connect * [ ] wwv +* [ ] reticulum ## Bluetooth TNC diff --git a/TODO.md b/TODO.md index 36a2ba3..f9490c6 100644 --- a/TODO.md +++ b/TODO.md @@ -1,10 +1,10 @@ # To-Do * [ ] Add Reticulum - * [ ] Add .reticulum/config with template support * [ ] Add rnsd systemd service (user) * [ ] Add nomadnet systemd service (user) * [ ] Add et-mode with encryption warning + * [ ] Add support for Bluetooth devices * [ ] et-mail * [ ] et-debug * [ ] et-index From 44a2495bc71b2d0d0c8fe05e3d9d4e6eabdbd9d4 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 12 May 2026 07:58:32 -0700 Subject: [PATCH 09/64] reticulum - Added initial user-level systemd services for Reticulum --- .../user/et-service-reticulum-1200.service | 20 +++++++++++++++++++ .../user/et-service-reticulum-300.service | 20 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 overlay/etc/skel/.config/systemd/user/et-service-reticulum-1200.service create mode 100644 overlay/etc/skel/.config/systemd/user/et-service-reticulum-300.service diff --git a/overlay/etc/skel/.config/systemd/user/et-service-reticulum-1200.service b/overlay/etc/skel/.config/systemd/user/et-service-reticulum-1200.service new file mode 100644 index 0000000..d721934 --- /dev/null +++ b/overlay/etc/skel/.config/systemd/user/et-service-reticulum-1200.service @@ -0,0 +1,20 @@ +# Author : Gaston Gonzalez +# Date : 12 May 2026 +# Purpose : User systemd unit file for EmComm Tools Reticulum 1200 baud +# : packet service. +# +# Usage: +# Check status : systemctl --user status et-service-reticulum-1200 +# Start service : systemctl --user start et-service-reticulum-1200 +# Stop service : systemctl --user stop et-service-reticulum-1200 +# Reload this config : systemctl --user daemon-reload + +[Unit] +Description=EmComm Tools Reticulum 1200 baud packet service + +[Service] +ExecStart=/opt/emcomm-tools/bin/et-reticulum start 1200 +Restart=no + +[Install] +WantedBy=multi-user.target diff --git a/overlay/etc/skel/.config/systemd/user/et-service-reticulum-300.service b/overlay/etc/skel/.config/systemd/user/et-service-reticulum-300.service new file mode 100644 index 0000000..fa1e79a --- /dev/null +++ b/overlay/etc/skel/.config/systemd/user/et-service-reticulum-300.service @@ -0,0 +1,20 @@ +# Author : Gaston Gonzalez +# Date : 12 May 2026 +# Purpose : User systemd unit file for EmComm Tools Reticulum 300 baud +# : packet service. +# +# Usage: +# Check status : systemctl --user status et-service-reticulum-300 +# Start service : systemctl --user start et-service-reticulum-300 +# Stop service : systemctl --user stop et-service-reticulum-300 +# Reload this config : systemctl --user daemon-reload + +[Unit] +Description=EmComm Tools Reticulum 300 baud packet service + +[Service] +ExecStart=/opt/emcomm-tools/bin/et-reticulum start 300 +Restart=no + +[Install] +WantedBy=multi-user.target From 21c50230961fabcd3224a5a6be52881f37034070 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 12 May 2026 08:27:10 -0700 Subject: [PATCH 10/64] reticulum - Initial work add Reticulum to et-mode --- overlay/opt/emcomm-tools/bin/et-mode | 40 +++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/overlay/opt/emcomm-tools/bin/et-mode b/overlay/opt/emcomm-tools/bin/et-mode index 3700d3b..65b86c4 100755 --- a/overlay/opt/emcomm-tools/bin/et-mode +++ b/overlay/opt/emcomm-tools/bin/et-mode @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 6 November 2024 -# Updated : 16 March 2026 +# Updated : 12 May 2026 # Purpose : Configures the system for a specific mode of operation # Use a simple text file to save the state of the last mode selected @@ -19,6 +19,7 @@ MODE_ID_BBS_CLIENT2="bbs-client2" MODE_ID_BBS_SERVER="bbs-server" MODE_ID_CHAT_CLIENT="chat-chattervox" MODE_ID_PACKET_DIGIPEATER="packet-digipeater" +MODE_ID_RETICULUM_PACKET="reticulum-packet" MODE_ID_WINLINK_ARDOP="winlink-ardop" MODE_ID_WINLINK_PACKET="winlink-packet" MODE_ID_WINLINK_VARA_HF="winlink-vara-hf" @@ -129,6 +130,27 @@ select_term_mode () { fi } +select_reticulum_mode () { + term_mode=() + term_mode+=("1200" "1200 baud (default for VHF/UHF)") + term_mode+=("300" "300 baud (HF)") + + TERM_MODE=$(dialog --clear --menu "Select a modem" 13 60 10 "${term_mode[@]}" 3>&1 1>&2 2>&3) + + dialog \ + --title "Note on Reticulum" \ + --yesno "Reticulum uses end-to-end encryption. Check your local laws and regulations and ensure that you can legally run this mode!" \ + 0 0 + exit_status=$? + + tput sgr 0 && clear + + if [ ${exit_status} -ne 0 ]; then + et-log "User canceled mode selection. Mode will not be started." + exit 1 + fi +} + wwv_mode () { dialog --title "Note on WWV" --msgbox "Manually set your radio to AM and tune it to one of the WWV frequencies appropriate for this operating time.\n\nTry: 2.5, 5, 10, 15 or 20 MHz." 0 0 tput sgr 0 && clear @@ -157,6 +179,7 @@ if [ -e "${HOME}/.wine32/drive_c/VARA/VARA.exe" ]; then fi options+=("${MODE_ID_TIME_WWV}" "Sync clock to WWV") +options+=("${MODE_ID_RETICULUM_PACKET}" "Reticulum over AX.25 Packet") # Prompt user for option and save exit status SELECTED_MODE=$(dialog --clear --menu "Select a mode:" 18 65 10 "${options[@]}" 3>&1 1>&2 2>&3) @@ -275,6 +298,21 @@ if [ $exit_status -eq 0 ]; then wwv_mode sudo /opt/emcomm-tools/sbin/wrapper-et-wwv.sh ;; + ${MODE_ID_RETICULUM_PACKET}) + select_reticulum_mode + et-log "Using ${TERM_MODE} as the modem." + + case "${TERM_MODE}" in + "1200") + start_and_wait_for_service et-service-reticulum-1200 + ;; + "300") + start_and_wait_for_service et-service-reticulum-300 + ;; + esac + + nomadnet + ;; *) et-log "Mode ${SELECTED_MODE} not yet supported" exit 1 From eaaa1e51d2e8040dfbca76fef882ff1eeccfe886 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 12 May 2026 08:41:09 -0700 Subject: [PATCH 11/64] reticulum - Updated et-kill-all to stop all Reticulum systemd services --- overlay/opt/emcomm-tools/bin/et-kill-all | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/overlay/opt/emcomm-tools/bin/et-kill-all b/overlay/opt/emcomm-tools/bin/et-kill-all index ed0b8b3..62839f9 100755 --- a/overlay/opt/emcomm-tools/bin/et-kill-all +++ b/overlay/opt/emcomm-tools/bin/et-kill-all @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 12 November 2024 -# Updated : 2 October 2025 +# Updated : 12 May 2026 # Purpose : Stops all EmComm Tools sound-based services (i.e. modems) and # amatuer radio applications to ensure a clean start for the next mode. @@ -21,6 +21,8 @@ stop_all_services() { systemctl --user stop et-service-winlink-ardop systemctl --user stop et-service-winlink-packet systemctl --user stop et-service-winlink-native-packet + systemctl --user stop et-service-reticulum-300 + systemctl --user stop et-service-reticulum-1200 systemctl --user stop et-service-ardop systemctl --user stop et-service-direwolf-300 systemctl --user stop et-service-direwolf-9600 From e634d0e119d924d38afac2dec263da66fac687de Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 12 May 2026 12:29:15 -0700 Subject: [PATCH 12/64] reticulum - Added basic NomadNet configuration file and Reticulum manual --- overlay/etc/skel/.nomadnetwork/config | 334 ++++++++++++++++++++++++++ scripts/install-offline-lib.json | 5 + 2 files changed, 339 insertions(+) create mode 100644 overlay/etc/skel/.nomadnetwork/config diff --git a/overlay/etc/skel/.nomadnetwork/config b/overlay/etc/skel/.nomadnetwork/config new file mode 100644 index 0000000..edb48ca --- /dev/null +++ b/overlay/etc/skel/.nomadnetwork/config @@ -0,0 +1,334 @@ +# This is the default Nomad Network config file. +# You should probably edit it to suit your needs and use-case, + +[logging] +# Valid log levels are 0 through 7: +# 0: Log only critical information +# 1: Log errors and lower log levels +# 2: Log warnings and lower log levels +# 3: Log notices and lower log levels +# 4: Log info and lower (this is the default) +# 5: Verbose logging +# 6: Debug logging +# 7: Extreme logging + +loglevel = 4 +destination = file + +[client] + +enable_client = yes +user_interface = text +downloads_path = ~/Downloads +notify_on_new_message = yes + +# By default, the peer is announced at startup +# to let other peers reach it immediately. +announce_at_start = yes + +# By default, the client will try to deliver a +# message via the LXMF propagation network, if +# a direct delivery to the recipient is not +# possible. +try_propagation_on_send_fail = yes + +# Nomadnet will periodically sync messages from +# LXMF propagation nodes by default, if any are +# present. You can disable this if you want to +# only sync when manually initiated. +periodic_lxmf_sync = yes + +# The sync interval in minutes. This value is +# equal to 6 hours (360 minutes) by default. +lxmf_sync_interval = 360 + +# By default, automatic LXMF syncs will only +# download 8 messages at a time. You can change +# this number, or set the option to 0 to disable +# the limit, and download everything every time. +lxmf_sync_limit = 8 + +# You can specify a required stamp cost for +# inbound messages to be accepted. Specifying +# a stamp cost will require untrusted senders +# that message you to include a cryptographic +# stamp in their messages. Performing this +# operation takes the sender an amount of time +# proportional to the stamp cost. As a rough +# estimate, a stamp cost of 8 will take less +# than a second to compute, and a stamp cost +# of 20 could take several minutes, even on +# a fast computer. +required_stamp_cost = None + +# You can signal stamp requirements to senders, +# but still accept messages with invalid stamps +# by setting this option to True. +accept_invalid_stamps = False + +# The maximum accepted unpacked size for mes- +# sages received directly from other peers, +# specified in kilobytes. Messages larger than +# this will be rejected before the transfer +# begins. +max_accepted_size = 500 + +# The announce stream will only show one entry +# per destination or node by default. You can +# change this to show as many announces as have +# been received, for every destination. +compact_announce_stream = yes + +[textui] + +# Amount of time to show intro screen +intro_time = 1 + +# You can specify the display theme. +# theme = light +theme = dark + +# Specify the number of colors to use +# valid colormodes are: +# monochrome, 16, 88, 256 and 24bit +# +# The default is a conservative 256 colors. +# If your terminal does not support this, +# you can lower it. Some terminals support +# 24 bit color. + +# colormode = monochrome +# colormode = 16 +# colormode = 88 +colormode = 256 +# colormode = 24bit + +# By default, unicode glyphs are used. If +# you have a Nerd Font installed, you can +# enable this for a better user interface. +# You can also enable plain text glyphs if +# your terminal doesn't support unicode. + +# glyphs = plain +glyphs = unicode +# glyphs = nerdfont + +# You can specify whether mouse events +# should be considered as input to the +# application. On by default. +mouse_enabled = True + +# What editor to use for editing text. +editor = nano + +# If you don't want the Guide section to +# show up in the menu, you can disable it. +hide_guide = no + +[node] + +# Whether to enable node hosting +enable_node = no + +# The node name will be visible to other +# peers on the network, and included in +# announces. +node_name = None + +# Automatic announce interval in minutes. +# 6 hours by default. +announce_interval = 360 + +# Whether to announce when the node starts. +announce_at_start = Yes + +# When Nomad Network is hosting a page-serving +# node, it can also act as an LXMF propagation +# node. This is a convenient feature that lets +# you easily set up and run a propagation node +# on the network, but it is not as fully +# featured as using the lxmd program to host a +# propagation node. For complete control and +# flexibility, use lxmd to run a PN. For a +# small local system or network, the built-in +# PN functionality will suffice for most cases. +# +# If there is already a large amount of +# propagation nodes on the network, or you +# simply want to run a pageserving-only node, +# you should disable running a propagation node. +# Due to lots of propagation nodes being +# available, this is currently the default. + +disable_propagation = Yes + +# For clients and other propagation nodes +# delivering messages via this node, you can +# configure the minimum required propagation +# stamp costs. All messages delivered to the +# propagation node network must have a valid +# propagation stamp, or they will be rejected. +# Clients automatically detect the stamp cost +# for the node they are delivering to, and +# compute a corresponding stamp before trying +# to deliver the message to the propagation +# node. +# +# Propagation stamps are easier to verify in +# large batches, and therefore also somewhat +# easier to compute for the senders. As such, +# a reasonable propagation stamp cost should +# be a bit higher than the normal peer-to-peer +# stamp costs. +# +# Propagation stamps does not incur any extra +# load for propagation nodes processing them, +# since they are only required to verify that +# they are correct, and only the generation +# is computationally costly. Setting a sensible +# propagation stamp cost (and periodically +# checking the average network consensus) helps +# keep spam and misuse out of the propagation +# node network. + +propagation_cost = 16 + +# The maximum amount of storage to use for +# the LXMF Propagation Node message store, +# specified in megabytes. When this limit +# is reached, LXMF will periodically remove +# messages in its message store. By default, +# LXMF prioritises keeping messages that are +# new and small. Large and old messages will +# be removed first. This setting is optional +# and defaults to 2 gigabytes. + +# message_storage_limit = 2000 + +# The maximum accepted transfer size per in- +# coming propagation message, in kilobytes. +# This sets the upper limit for the size of +# single messages accepted onto this node. + +max_transfer_size = 256 + +# The maximum accepted transfer size per in- +# coming propagation node sync. +# +# If a node wants to propagate a larger number +# of messages to this node, than what can fit +# within this limit, it will prioritise sending +# the smallest messages first, and try again +# with any remaining messages at a later point. + +max_sync_size = 10240 + +# You can tell the LXMF message router to +# prioritise storage for one or more +# destinations. If the message store reaches +# the specified limit, LXMF will prioritise +# keeping messages for destinations specified +# with this option. This setting is optional, +# and generally you do not need to use it. + +# prioritise_destinations = 41d20c727598a3fbbdf9106133a3a0ed, d924b81822ca24e68e2effea99bcb8cf + +# You can configure the maximum number of other +# propagation nodes that this node will peer +# with automatically. The default is 20. + +# max_peers = 20 + +# You can configure a list of static propagation +# node peers, that this node will always be +# peered with, by specifying a list of +# destination hashes. + +# static_peers = e17f833c4ddf8890dd3a79a6fea8161d, 5a2d0029b6e5ec87020abaea0d746da4 + +# You can specify the interval in minutes for +# rescanning the hosted pages path. By default, +# this option is disabled, and the pages path +# will only be scanned on startup. + +# page_refresh_interval = 0 + +# You can specify the interval in minutes for +# rescanning the hosted files path. By default, +# this option is disabled, and the files path +# will only be scanned on startup. + +# file_refresh_interval = 0 + +[printing] + +# You can configure Nomad Network to print +# various kinds of information and messages. + +# Printing messages is disabled by default + +print_messages = No + +# You can configure a custom template for +# message printing. If you uncomment this +# option, set a path to the template and +# restart Nomad Network, a default template +# will be created that you can edit. + +# message_template = ~/.nomadnetwork/print_template_msg.txt + +# You can configure Nomad Network to only +# print messages from trusted destinations. + +# print_from = trusted + +# Or specify the source LXMF addresses that +# will automatically have messages printed +# on arrival. + +# print_from = 76fe5751a56067d1e84eef3e88eab85b, 0e70b5848eb57c13154154feaeeb89b7 + +# Or allow printing from anywhere, if you +# are feeling brave and adventurous. + +# print_from = everywhere + +# You can configure the printing command. +# This will use the default CUPS printer on +# your system. + +print_command = lp + +# You can specify what printer to use +# print_command = lp -d [PRINTER_NAME] + +# Or specify more advanced options. This +# example works well for small thermal- +# roll printers: +# print_command = lp -d [PRINTER_NAME] -o cpi=16 -o lpi=8 + +# This one is more suitable for full-sheet +# printers. It will print a QR code at the center of any media +# your printer will accept, print in portrait mode, and move the message to +# the top of the print queue: +# print_command = lp -d [PRINTER_NAME] -o job-priority=100 -o media=Custom.75x75mm -o orientation-requested=3 + +# But you can modify the size to fit your needs. +# The custom media option accepts millimeters, centimeters, and +# inches in a width by length format like so: +# -o media=Custom.[WIDTH]x[LENGTH][mm,cm,in] +# +# The job priority option accepts 1-100, though you can remove it +# entirely if you aren't concerned with a print queue: +# -o job-priority=[1-100] +# +# Finally, the orientation option allows for 90 degree rotations beginning with 3, so: +# -o orientation-requested=4 (landscape, 90 degrees) +# -o orientation-requested=5 (reverse portrait, 180 degrees) +# +# Here is the full command with the recommended customizable variables: +# print_command = lp -d [PRINTER_NAME] -o job-priority=[N] -o media=[MEDIA_SIZE] -o orientation-requested=[N] -o sides=one-sided + +# For example, here's a configuration for USB thermal printer that uses the POS-58 PPD driver +# with rolls 47.98x209.9mm in size: +# print_command = lp -d [PRINTER_NAME] -o job-priority=100 -o media=custom_47.98x209.9mm_47.98x209.9mm -o sides=one-sided diff --git a/scripts/install-offline-lib.json b/scripts/install-offline-lib.json index 871d626..b901f68 100644 --- a/scripts/install-offline-lib.json +++ b/scripts/install-offline-lib.json @@ -43,5 +43,10 @@ "url": "https://reticulum.betweentheborders.com/primer.pdf", "file": "primer.pdf", "dir": "reticulum" + }, + { + "url": "https://github.com/markqvist/Reticulum/releases/download/1.2.5/Reticulum.Manual.pdf", + "file": "Reticulum.Manual.pdf", + "dir": "reticulum" } ] From 9118989b95b3438812e230e59ac0adedbfd23211 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 12 May 2026 14:18:07 -0700 Subject: [PATCH 13/64] debranding - Added missing steps to start apply EmComm Tools brand --- scripts/debrand.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/scripts/debrand.sh b/scripts/debrand.sh index 8de1229..8d1bcf0 100755 --- a/scripts/debrand.sh +++ b/scripts/debrand.sh @@ -1,14 +1,24 @@ #!/bin/bash # Author : Gaston Gonzalez # Date : 7 May 2026 -# Updated : 11 May 2026 +# Updated : 12 May 2026 # Purpose : Debrand Ubuntu # # Post Conditions: -# 1. Plymouth splash screen displays on Live USB boot +# 1. EmComm Tools splash screen displays on Live USB boot +# 2. Installer shows EmComm Tools slideshow et-log "Debranding Ubuntu..." +et-log "Customizing Installer..." +apt install \ + ubiquity-slideshow-ubuntu \ + -y +cp -v -r ../overlay/usr/share/ubiquity-slideshow/* /usr/share/ubiquity-slideshow + +et-log "Customizing boot screen..." +cp -v -r ../overlay/usr/share/plymouth/* /usr/share/plymouth + # A new kernel is required as the initramfs that Cubic uses is # based on the base ISO by default. et-log "Installing latest kernel..." From 7cfa0d58a6be1a7c4339b08a03eee98210aafbd3 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Wed, 13 May 2026 07:39:59 -0700 Subject: [PATCH 14/64] reticulum - Added support for creating ~/.reticulum if does not exist --- TODO.md | 10 ++++++---- overlay/opt/emcomm-tools/bin/et-reticulum | 9 ++++++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/TODO.md b/TODO.md index f9490c6..7d4be29 100644 --- a/TODO.md +++ b/TODO.md @@ -1,10 +1,12 @@ # To-Do * [ ] Add Reticulum - * [ ] Add rnsd systemd service (user) - * [ ] Add nomadnet systemd service (user) - * [ ] Add et-mode with encryption warning - * [ ] Add support for Bluetooth devices + * [ ] Add solution for handling first start + * [ ] et-user-backup + * [ ] ~/.reticulum/storage/identities + * [ ] ~/.nomadnetwork/storage + * [ ] Add PnP support for LoRa devices + * [ ] Add support for Bluetooth devices (et-uv-pro) * [ ] et-mail * [ ] et-debug * [ ] et-index diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum index 9ffbe10..d5c94bc 100755 --- a/overlay/opt/emcomm-tools/bin/et-reticulum +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -2,6 +2,7 @@ # # Author : Gaston Gonzalez # Date : 12 May 2026 +# Updated : 13 May 2026 # Purpose : Wrapper script for starting Reticulum with PnP support # # Preconditions: @@ -14,7 +15,8 @@ . /opt/emcomm-tools/bin/et-common APP="Reticulum" -RETICULUM_CONF_FILE="${HOME}/.reticulum/config" +RETICULUM_CONF_DIR="${HOME}/.reticulum" +RETICULUM_CONF_FILE="${RETICULUM_CONF_DIR}/config" usage() { echo "usage: $(basename $0) " @@ -49,6 +51,11 @@ case "${MODE}" in ;; esac +if [[ ! -e "${RETICULUM_CONF_DIR}" ]]; then + et-log "Creating missing configuration directory: ${RETICULUM_CONF_DIR}" + mkdir -p "${RETICULUM_CONF_DIR}" +fi + if [[ ! -e "${RETICULUM_TEMPLATE_CONF_FILE}" ]]; then et-log "${RETICULUM_TEMPLATE_CONF_FILE} does not exist. Exiting." notify-user "Config file does not exist. Can't start Reticulum." From 0a14708fae04315e27739d546bc6be97db23a0c7 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Thu, 14 May 2026 21:49:46 -0700 Subject: [PATCH 15/64] reticulum - Added support for MeshChat to et-mode; enabled Reticulum to support multi-interface routing --- overlay/opt/emcomm-tools/bin/et-mode | 25 +++++++++-- .../template.d/reticulum/config.ax25.1200 | 4 +- scripts/install-meshchat.sh | 42 +++++++++++++++++++ scripts/install.sh | 5 ++- 4 files changed, 68 insertions(+), 8 deletions(-) create mode 100755 scripts/install-meshchat.sh diff --git a/overlay/opt/emcomm-tools/bin/et-mode b/overlay/opt/emcomm-tools/bin/et-mode index 65b86c4..507525c 100755 --- a/overlay/opt/emcomm-tools/bin/et-mode +++ b/overlay/opt/emcomm-tools/bin/et-mode @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 6 November 2024 -# Updated : 12 May 2026 +# Updated : 13 May 2026 # Purpose : Configures the system for a specific mode of operation # Use a simple text file to save the state of the last mode selected @@ -19,7 +19,8 @@ MODE_ID_BBS_CLIENT2="bbs-client2" MODE_ID_BBS_SERVER="bbs-server" MODE_ID_CHAT_CLIENT="chat-chattervox" MODE_ID_PACKET_DIGIPEATER="packet-digipeater" -MODE_ID_RETICULUM_PACKET="reticulum-packet" +MODE_ID_RETICULUM_MESHCHAT="reticulum-meshchat" +MODE_ID_RETICULUM_NOMADNET="reticulum-nomadnet" MODE_ID_WINLINK_ARDOP="winlink-ardop" MODE_ID_WINLINK_PACKET="winlink-packet" MODE_ID_WINLINK_VARA_HF="winlink-vara-hf" @@ -179,7 +180,8 @@ if [ -e "${HOME}/.wine32/drive_c/VARA/VARA.exe" ]; then fi options+=("${MODE_ID_TIME_WWV}" "Sync clock to WWV") -options+=("${MODE_ID_RETICULUM_PACKET}" "Reticulum over AX.25 Packet") +options+=("${MODE_ID_RETICULUM_MESHCHAT}" "Reticulum MeshChat over AX.25 Packet") +options+=("${MODE_ID_RETICULUM_NOMADNET}" "Reticulum NomadNet over AX.25 Packet") # Prompt user for option and save exit status SELECTED_MODE=$(dialog --clear --menu "Select a mode:" 18 65 10 "${options[@]}" 3>&1 1>&2 2>&3) @@ -298,7 +300,22 @@ if [ $exit_status -eq 0 ]; then wwv_mode sudo /opt/emcomm-tools/sbin/wrapper-et-wwv.sh ;; - ${MODE_ID_RETICULUM_PACKET}) + ${MODE_ID_RETICULUM_MESHCHAT}) + select_reticulum_mode + et-log "Using ${TERM_MODE} as the modem." + + case "${TERM_MODE}" in + "1200") + start_and_wait_for_service et-service-reticulum-1200 + ;; + "300") + start_and_wait_for_service et-service-reticulum-300 + ;; + esac + + et-meshchat + ;; + ${MODE_ID_RETICULUM_NOMADNET}) select_reticulum_mode et-log "Using ${TERM_MODE} as the modem." diff --git a/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.1200 b/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.1200 index 4c55d13..dc51934 100644 --- a/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.1200 +++ b/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.1200 @@ -17,7 +17,7 @@ # always-on. This directive is optional and can be removed # for brevity. - enable_transport = False + enable_transport = True # By default, the first program to launch the Reticulum @@ -115,7 +115,7 @@ [[Default Interface]] type = AutoInterface - enabled = No + enabled = Yes [[Packet Radio AX25 KISS]] type = AX25KISSInterface diff --git a/scripts/install-meshchat.sh b/scripts/install-meshchat.sh new file mode 100755 index 0000000..1074413 --- /dev/null +++ b/scripts/install-meshchat.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# Author : Gaston Gonzalez +# Date : 13 May 2026 +# Purpose : Install MeshChat for Reticulum +set -e +trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG +trap 'et-log "\"${last_command}\" command failed with exit code $?."' ERR + +. ./env.sh +. ../overlay/opt/emcomm-tools/bin/et-common + +APP=ReticulumMeshChat +VERSION=2.3.0 +INSTALL_DIR="/opt/${APP}-${VERSION}" +INSTALL_BIN_DIR="${INSTALL_DIR}/bin" +LINK_PATH="/opt/${APP}" + +DOWNLOAD_FILE="${APP}-v${VERSION}-linux.AppImage" +URL="https://github.com/liamcottle/reticulum-meshchat/releases/download/v${VERSION}/${DOWNLOAD_FILE}" + +et-log "Installing ${APP} ${VERSION}..." + +if [[ ! -e ${DOWNLOAD_FILE} ]]; then + download_with_retries ${URL} ${DOWNLOAD_FILE} +fi + +chmod -v 755 ${DOWNLOAD_FILE} + +[[ ! -e "${INSTALL_BIN_DIR}" ]] && mkdir -v -p "${INSTALL_BIN_DIR}" + +mv ${DOWNLOAD_FILE} ${INSTALL_BIN_DIR} + +ET_WRAPPER_SCRIPT="${ET_HOME}/bin/et-meshchat" + +et-log "Creating wrapper script: ${ET_WRAPPER_SCRIPT}" +cat < ${ET_WRAPPER_SCRIPT} +#!/bin/bash + +${INSTALL_BIN_DIR}/${DOWNLOAD_FILE} +EOF + +chmod -v 755 ${ET_WRAPPER_SCRIPT} diff --git a/scripts/install.sh b/scripts/install.sh index 89fa035..2e283d6 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 16 March 2024 -# Updated : 11 May 2026 +# Updated : 13 May 2026 # Purpose : Main installer for EmComm Tools Community (ETC) . ./env.sh @@ -119,8 +119,9 @@ exitIfNotRoot # Security Patches ./patch-copy-fail.sh -# Install Reticulum and NomadNet +# Install Reticulum and related applications (NomadNet, MeshChat) ./install-reticulum.sh +./install-meshchat.sh # Debrand Ubuntu ./debrand.sh From 1548e4101e637cc94c97d93ea6591daa87bc439d Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Fri, 15 May 2026 13:34:44 -0700 Subject: [PATCH 16/64] reticulum - Updated 300 baud configuration to match 1200 baud conifiguration --- .../emcomm-tools/conf/template.d/reticulum/config.ax25.300 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.300 b/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.300 index 4c55d13..dc51934 100644 --- a/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.300 +++ b/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.300 @@ -17,7 +17,7 @@ # always-on. This directive is optional and can be removed # for brevity. - enable_transport = False + enable_transport = True # By default, the first program to launch the Reticulum @@ -115,7 +115,7 @@ [[Default Interface]] type = AutoInterface - enabled = No + enabled = Yes [[Packet Radio AX25 KISS]] type = AX25KISSInterface From 2235d9eefca69125e0d9af59ead91ac0b7945d7b Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Fri, 15 May 2026 15:01:12 -0700 Subject: [PATCH 17/64] Reticulum - Added support for running MeshChat at 1200 baud packet from the Desktop Activities --- overlay/opt/emcomm-tools/bin/et-meshchat-app | 44 +++++++++++++++++++ .../applications/et-meshchat-1200.desktop | 11 +++++ scripts/install-meshchat.sh | 8 ++++ 3 files changed, 63 insertions(+) create mode 100755 overlay/opt/emcomm-tools/bin/et-meshchat-app create mode 100644 overlay/usr/share/applications/et-meshchat-1200.desktop diff --git a/overlay/opt/emcomm-tools/bin/et-meshchat-app b/overlay/opt/emcomm-tools/bin/et-meshchat-app new file mode 100755 index 0000000..2d369df --- /dev/null +++ b/overlay/opt/emcomm-tools/bin/et-meshchat-app @@ -0,0 +1,44 @@ +#!/bin/bash +# +# Author : Gaston Gonzalez +# Date : 15 May 2026 +# Purpose : Wrapper script for starting MeshChat with PnP support +# +# Preconditions +# 1. Supported radio and audio interface are connected and properly detected +# +# Postconditions +# 1. Stop all running EmComm Tools modes +# 2. Start Dire Wolf in appropriate mode +# 3. Start Reticulum (rnsd) in appropriate mode +. /opt/emcomm-tools/bin/et-common + +usage() { + echo "usage: $(basename $0) " + echo " " + echo " 1200 - Run MeshChat with AX.25 interface over VHF/UHF (1200 baud)" + echo " 300 - Run MeshChat with AX.25 interface over HF (300 baud)" +} + +if [ $# -ne 1 ]; then + usage + exit 1 +fi + +et-kill-all + +MODE=$1 +case "${MODE}" in + "1200") + start_and_wait_for_service et-service-reticulum-1200 + ;; + "300") + start_and_wait_for_service et-service-reticulum-300 + ;; + *) + et-log "Unsupported mode." + exit 1 + ;; +esac + +et-meshchat diff --git a/overlay/usr/share/applications/et-meshchat-1200.desktop b/overlay/usr/share/applications/et-meshchat-1200.desktop new file mode 100644 index 0000000..a128eaf --- /dev/null +++ b/overlay/usr/share/applications/et-meshchat-1200.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Version=1.0 +Name=MeshChat 1200 +Comment=MeshChat over Reticulum using 1200 baud packet +Exec=/opt/emcomm-tools/bin/et-meshchat-app 1200 +Icon=/opt/ReticulumMeshChat-2.3.0/logo-chat-bubble.png +Terminal=false +X-MultipleArgs=false +Type=Application +Categories=Radio; +StartupNotify=true diff --git a/scripts/install-meshchat.sh b/scripts/install-meshchat.sh index 1074413..58fc536 100755 --- a/scripts/install-meshchat.sh +++ b/scripts/install-meshchat.sh @@ -1,6 +1,7 @@ #!/bin/bash # Author : Gaston Gonzalez # Date : 13 May 2026 +# Updated : 15 May 2026 # Purpose : Install MeshChat for Reticulum set -e trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG @@ -40,3 +41,10 @@ ${INSTALL_BIN_DIR}/${DOWNLOAD_FILE} EOF chmod -v 755 ${ET_WRAPPER_SCRIPT} + +ICON=logo-chat-bubble.png +ICON_URL="https://raw.githubusercontent.com/thetechprepper/reticulum-meshchat/master/logo/${ICON}" +download_with_retries ${ICON_URL} ${ICON} +mv ${ICON} ${INSTALL_DIR} + +cp ../overlay/usr/share/applications/et-meshchat-1200.desktop /usr/share/applications From fb23857f22617cef87fa88eda4d4df7448a85e2f Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Fri, 12 Jun 2026 14:09:43 -0700 Subject: [PATCH 18/64] misc - Added offline Heltec v3 and v4 datasheets; added a very early design for the potential Reticulum blueprint configuration subsystem --- overlay/etc/skel/.reticulum/README.md | 43 ++++++ overlay/etc/skel/.reticulum/config | 10 -- .../config.blueprint.permanent-transport-node | 133 ++++++++++++++++++ .../Desktop/offline/crypto/gpg-cheatsheet.md | 3 +- .../template.d/reticulum/config.ax25.1200 | 34 +++++ scripts/install-offline-lib.json | 10 ++ 6 files changed, 222 insertions(+), 11 deletions(-) create mode 100644 overlay/etc/skel/.reticulum/README.md create mode 100644 overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node diff --git a/overlay/etc/skel/.reticulum/README.md b/overlay/etc/skel/.reticulum/README.md new file mode 100644 index 0000000..4e0955c --- /dev/null +++ b/overlay/etc/skel/.reticulum/README.md @@ -0,0 +1,43 @@ +# Emcomm Tools Configuration for Reticulum + +EmComms Tools provides plug-and-play support to reduce the barrier to +entry for non-technical users. Reticulum is a very powerful tool for +building user-defined networks. This has the effect of allowing for +users to create sophisticated, end-to-end encrypted networks that can +leverage many different transport mediums. While this is powerful, it +has the potential for introducing complexity for new users. + +This document describes the approach that EmComm Tools takes for +supporting plug-and-play support with near-zero configuration. + +## Blueprint Configuration Files + +EmComm Tools uses a _blueprint_ approach for defining a set of reference +network configurations to help new users get started. + +config.blueprint.permanent-transport-node + +## Replacement Tokens + +Replacement tokens are defined by `{{TOKEN}}` where `TOKEN` is one of +the supported tokens below. + +``` +ET_CALLSIGN +ET_RETICULUM_INTERFACE_AUTO_ENABLED +ET_RETICULUM_INTERFACE_AX25KISS_ENABLED +ET_RETICULUM_INTERFACE_RNODE_BANDWIDTH +ET_RETICULUM_INTERFACE_RNODE_CODINGRATE +ET_RETICULUM_INTERFACE_RNODE_ENABLED +ET_RETICULUM_INTERFACE_RNODE_FREQUENCY +ET_RETICULUM_INTERFACE_RNODE_SPREADINGFACTOR +ET_RETICULUM_INTERFACE_RNODE_TXPOWER +... +``` + +* Valid characters are capitalized letters (`A-Z`) and underscores (`_`). +* Start with the prefix: `ET_`. +* Reticulum specific tokens start with the prefix: `ET_RETICULUM_`. + + + diff --git a/overlay/etc/skel/.reticulum/config b/overlay/etc/skel/.reticulum/config index 4c55d13..e0e6a83 100644 --- a/overlay/etc/skel/.reticulum/config +++ b/overlay/etc/skel/.reticulum/config @@ -115,14 +115,4 @@ [[Default Interface]] type = AutoInterface - enabled = No - - [[Packet Radio AX25 KISS]] - type = AX25KISSInterface enabled = Yes - - callsign = {{ET_CALLSIGN}} - ssid = 1 - - port = /tmp/kisstnc - mtu = 256 diff --git a/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node b/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node new file mode 100644 index 0000000..d781d0e --- /dev/null +++ b/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node @@ -0,0 +1,133 @@ +# Author : Gaston Gonzalez +# Date : 7 June 2026 +# Updated : 7 June 2026 +# Blueprint : Permament Transport Node +# Purpose : This coniguration is a blueprint (i.e. reference +# configuration) for running a 24x7 transport +# Reticulum node with multiple interfaces. + +[reticulum] + + # If you enable Transport, your system will route traffic + # for other peers, pass announces and serve path requests. + # This should only be done for systems that are suited to + # act as transport nodes, ie. if they are stationary and + # always-on. This directive is optional and can be removed + # for brevity. + + enable_transport = True + + + # By default, the first program to launch the Reticulum + # Network Stack will create a shared instance, that other + # programs can communicate with. Only the shared instance + # opens all the configured interfaces directly, and other + # local programs communicate with the shared instance over + # a local socket. This is completely transparent to the + # user, and should generally be turned on. This directive + # is optional and can be removed for brevity. + + share_instance = Yes + + + # If you want to run multiple *different* shared instances + # on the same system, you will need to specify different + # instance names for each. On platforms supporting domain + # sockets, this can be done with the instance_name option: + + instance_name = default + +# You can configure whether Reticulum should discover +# available interfaces from other Transport Instances over +# the network. If this option is enabled, Reticulum will +# collect interface information discovered from the network. + +# discover_interfaces = No + + +# You can configure Reticulum to panic and forcibly close +# if an unrecoverable interface error occurs, such as the +# hardware device for an interface disappearing. This is +# an optional directive, and can be left out for brevity. +# This behaviour is disabled by default. + +# panic_on_interface_error = No + + +# If you're connecting to a large external network, you +# can use one or more external blackhole list to block +# spammy and excessive announces onto your network. This +# funtionality is especially useful if you're hosting public +# entrypoints or gateways. The list source below provides a +# functional example, but better, more timely maintained +# lists probably exist in the community. + +# blackhole_sources = 521c87a83afb8f29e4455e77930b973b + + +[logging] + # Valid log levels are 0 through 7: + # 0: Log only critical information + # 1: Log errors and lower log levels + # 2: Log warnings and lower log levels + # 3: Log notices and lower log levels + # 4: Log info and lower (this is the default) + # 5: Verbose logging + # 6: Debug logging + # 7: Extreme logging + + loglevel = 4 + + +[interfaces] + + [[Default Interface]] + type = AutoInterface + enabled = {{ET_RETICULUM_INTERFACE_AUTO_ENABLED}} + + [[Packet Radio AX.25 KISS]] + type = AX25KISSInterface + enabled = {{ET_RETICULUM_INTERFACE_AX25KISS_ENABLED}} + + callsign = {{ET_CALLSIGN}} + ssid = 1 + + port = /tmp/kisstnc + mtu = 256 + + [[RNode LoRa Interface]] + type = RNodeInterface + mode = ap + enabled = {{ET_RETICULUM_INTERFACE_RNODE_ENABLED}} + + port = /dev/et-lora + + # Set frequency to 915 MHz + frequency = 915000000 + #frequency = {{ET_RETICULUM_INTERFACE_RNODE_FREQUENCY}} + + # Set LoRa bandwidth to 125 KHz + bandwidth = 125000 + #bandwidth = {{ET_RETICULUM_INTERFACE_RNODE_BANDWIDTH}} + + # Set TX power in dBm + # 7 dBm = 5 mW + # 17 dbm = 50 mW + # 20 dbm = 100 mW + # 22 dbm = 158 mW + # 28 dbm = 631 mW + txpower = 22 + #txpower = {{ET_RETICULUM_INTERFACE_RNODE_TXPOWER}} + + # Select spreading factor 8. Valid + # range is 7 through 12, with 7 + # being the fastest and 12 having + # the longest range. + spreadingfactor = 9 + #spreadingfactor = {{ET_RETICULUM_INTERFACE_RNODE_SPREADINGFACTOR}} + + # Select coding rate 5. Valid range + # is 5 throough 8, with 5 being the + # fastest, and 8 the longest range. + codingrate = 5 + #codingrate = {{ET_RETICULUM_INTERFACE_RNODE_CODINGRATE}} diff --git a/overlay/etc/skel/Desktop/offline/crypto/gpg-cheatsheet.md b/overlay/etc/skel/Desktop/offline/crypto/gpg-cheatsheet.md index fd1cfca..667c355 100644 --- a/overlay/etc/skel/Desktop/offline/crypto/gpg-cheatsheet.md +++ b/overlay/etc/skel/Desktop/offline/crypto/gpg-cheatsheet.md @@ -122,7 +122,8 @@ standard that provides strong security and works well for radio use due to smaller key sizes. 1. Create a primary key for signing using ECC. Replace FIRSTNAME, - LASTNAME, and EMAIL (keep the < and > characters). + LASTNAME, and EMAIL. NOTE: You MUST keep `<` and `>` characters around + your EMAIL. For example: `John Doe `. gpg --quick-generate-key "FIRSTNAME LASTNAME " ed25519 sign 0 diff --git a/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.1200 b/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.1200 index dc51934..b574109 100644 --- a/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.1200 +++ b/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.1200 @@ -126,3 +126,37 @@ port = /tmp/kisstnc mtu = 256 + + [[RNode LoRa Interface]] + type = RNodeInterface + enabled = yes + + # Connect via Wi-Fi + port = tcp://192.168.8.167 + +# # Add PnP support: /dev/et-lora +# port = /dev/ttyACM1 + + + # Set frequency to 915 MHz + frequency = 915000000 + + # Set LoRa bandwidth to 125 KHz + bandwidth = 125000 + + # Set TX power in dBm + # 7 dBm = 5 mW + # 17 dbm = + # 22 dbm = + txpower = 17 + + # Select spreading factor 8. Valid + # range is 7 through 12, with 7 + # being the fastest and 12 having + # the longest range. + spreadingfactor = 9 + + # Select coding rate 5. Valid range + # is 5 throough 8, with 5 being the + # fastest, and 8 the longest range. + codingrate = 5 diff --git a/scripts/install-offline-lib.json b/scripts/install-offline-lib.json index b901f68..444ea6d 100644 --- a/scripts/install-offline-lib.json +++ b/scripts/install-offline-lib.json @@ -9,6 +9,16 @@ "file": "bpq-user-and-sysop-commands.pdf", "dir": "bbs/bpq" }, + { + "url": "https://resource.heltec.cn/download/WiFi_LoRa_32_V3/HTIT-WB32LA_V3.2.pdf", + "file": "HTIT-WB32LA_V3.2.pdf", + "dir": "lora/heltec" + }, + { + "url": "https://resource.heltec.cn/download/WiFi_LoRa_32_V4/datasheet/WiFi_LoRa_32_V4.2.0.pdf", + "file": "WiFi_LoRa_32_V4.2.0.pdf", + "dir": "lora/heltec" + }, { "url": "https://www.icomamerica.com/api/download.php?page_id=171&fl=JTJGdXBsb2FkcyUyRlVTQV9CYW5kX1BsYW4lMkZCYW5kX1BsYW5fTWFwJTJGQW1hdHVlckdyaWRTcXVhcmVNYXBfVVNBJTVCMTMlNUQucGRm", "file": "icom-us-grid.pdf", From 43e6895116cd21aa8a29bdb3823dc91484b27b63 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 14 Jun 2026 14:26:25 -0700 Subject: [PATCH 19/64] lora - Initial support for introducing PnP for LoRa devices. The Heltec v3 collides with chip sets used by et-radio. Will address with a solution in a future commit on this branch --- overlay/etc/skel/.conkyrc | 17 +++++++------- overlay/etc/udev/rules.d/100-et-lora.rules | 26 +++++++++++++++++++++ overlay/opt/emcomm-tools/bin/et-system-info | 12 +++++++++- 3 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 overlay/etc/udev/rules.d/100-et-lora.rules diff --git a/overlay/etc/skel/.conkyrc b/overlay/etc/skel/.conkyrc index 5b55577..cf0a64d 100644 --- a/overlay/etc/skel/.conkyrc +++ b/overlay/etc/skel/.conkyrc @@ -18,33 +18,34 @@ conky.config = { conky.text = [[ ${font DejaVu Sans:bold:size=10}${color #8d5133}${alignc}DATE/TIME -${font DejaVu Sans Mono:size=11}${color yellow}${alignc}${time %A, %B %d %Y} +${font DejaVu Sans Mono:size=10}${color yellow}${alignc}${time %A, %B %d %Y} Local: ${alignr}${time %H:%M:%S} UTC: ${alignr}${tztime UTC %H:%M:%S} GPS Time: ${alignr}${execpi 30 et-system-info et-time} ${font DejaVu Sans:bold:size=10}${color #8d5133}${alignc}SYSTEM -${font DejaVu Sans Mono:size=11}${color yellow}Uptime : ${uptime} +${font DejaVu Sans Mono:size=10}${color yellow}Uptime : ${uptime} CPU Util : ${cpu}% Disk Free: ${fs_free /} ${font DejaVu Sans:bold:size=10}${color #8d5133}${alignc}NETWORK -${font DejaVu Sans Mono:size=11}${color yellow}IP: ${execpi 60 /opt/emcomm-tools/bin/et-system-info ip} +${font DejaVu Sans Mono:size=10}${color yellow}IP: ${execpi 60 /opt/emcomm-tools/bin/et-system-info ip} ${font DejaVu Sans:bold:size=10}${color #8d5133}${alignc}INTERFACES -${font DejaVu Sans Mono:size=11}${color yellow}Radio: ${execpi 10 et-system-info active-radio} +${font DejaVu Sans Mono:size=10}${color yellow}Radio: ${execpi 10 et-system-info active-radio} CAT : ${execpi 10 et-system-info et-cat} GPS : ${execpi 10 et-system-info et-gps} Audio: ${execpi 10 et-system-info et-audio} -${if_existing /dev/et-sdr}SDR : ${execpi 10 et-system-info et-sdr}${endif} +SDR : ${execpi 10 et-system-info et-sdr} +LoRa : ${execpi 10 et-system-info et-lora} ${font DejaVu Sans:bold:size=10}${color #8d5133}${alignc}OPERATOR -${font DejaVu Sans Mono:size=11}${color yellow}Callsign: ${execpi 10 et-system-info callsign} +${font DejaVu Sans Mono:size=10}${color yellow}Callsign: ${execpi 10 et-system-info callsign} Grid : ${execpi 10 et-system-info grid} ${font DejaVu Sans:bold:size=10}${color white}${alignc}MODE -${font DejaVu Sans:bold:size=11}${color red}${alignc}${execpi 10 et-system-info et-mode} +${font DejaVu Sans:bold:size=10}${color red}${alignc}${execpi 10 et-system-info et-mode} -${font DejaVu Sans:bold:size=9}${color grey}${alignc}${execp /opt/emcomm-tools/bin/et-system-info release} +${font DejaVu Sans:bold:size=8}${color grey}${alignc}${execp /opt/emcomm-tools/bin/et-system-info release} ]]; diff --git a/overlay/etc/udev/rules.d/100-et-lora.rules b/overlay/etc/udev/rules.d/100-et-lora.rules new file mode 100644 index 0000000..aa3c398 --- /dev/null +++ b/overlay/etc/udev/rules.d/100-et-lora.rules @@ -0,0 +1,26 @@ +# Author : Gaston Gonzalez +# Date : 14 June 2026 +# Purpose : udev rules for supported LoRa devices +# +# Supported Devices +# 1. Heltec v4 +# +# Preconditions: +# 1. LoRa device connected via USB cable +# +# Postconditions: +# 1. /dev/et-lora created + +#KERNEL=="swradio0", \ +# GROUP="dialout", MODE="0660", SYMLINK+="et-sdr" + +# Heltec v4 +SUBSYSTEM=="usb", ATTRS{idVendor}=="303a", ATTRS{idProduct}=="1001", \ + GROUP="dialout", MODE="0660", SYMLINK+="et-lora" + + +# Heltec v3 +# Uses the CP210x so this will collide with radios already supported by et-radio +SUBSYSTEM=="usb", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", \ + GROUP="dialout", MODE="0660", SYMLINK+="et-lora" + diff --git a/overlay/opt/emcomm-tools/bin/et-system-info b/overlay/opt/emcomm-tools/bin/et-system-info index dfcdd69..ca47a20 100755 --- a/overlay/opt/emcomm-tools/bin/et-system-info +++ b/overlay/opt/emcomm-tools/bin/et-system-info @@ -3,7 +3,7 @@ # Author : Gaston Gonzalez # Author : William McKeehan # Date : 6 October 2024 -# Updated : 5 September 2025 +# Updated : 14 June 2025 # Purpose : Utility script for dumping system information function usage() { @@ -13,6 +13,7 @@ function usage() { echo " et-audio - Show state of audio interface" echo " et-audio-card - Display audio card and device: ," echo " et-cat - Show state of CAT control interface" + echo " et-lora - Show state of LoRa interface" echo " et-gps - Show state of GPS interface" echo " et-time - Show if time is synched via GPS" echo " et-mode - Show current mode" @@ -143,6 +144,15 @@ case $1 in fi ;; + et-lora) + # 1. Check if the symlink was created by the udev rules + if [ -e /dev/et-lora]; then + echo "Connected"; + else + echo "Not connected"; + fi + + ;; et-sdr) # 1. Check if the symlink was created by the udev rules if [ -e /dev/et-sdr ]; then From f6b72ad8e53ec3d84df208e6f7b9ddc5af76ad18 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 14 Jun 2026 14:31:34 -0700 Subject: [PATCH 20/64] lora - Fixed syntax error for et-lora case --- overlay/opt/emcomm-tools/bin/et-system-info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/overlay/opt/emcomm-tools/bin/et-system-info b/overlay/opt/emcomm-tools/bin/et-system-info index ca47a20..d748d77 100755 --- a/overlay/opt/emcomm-tools/bin/et-system-info +++ b/overlay/opt/emcomm-tools/bin/et-system-info @@ -146,7 +146,7 @@ case $1 in ;; et-lora) # 1. Check if the symlink was created by the udev rules - if [ -e /dev/et-lora]; then + if [ -e /dev/et-lora ]; then echo "Connected"; else echo "Not connected"; From e6aa120454bb6193cb9f39484b3cc1c288f83467 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 14 Jun 2026 14:51:04 -0700 Subject: [PATCH 21/64] lora - Move LoRa devices rules ahead of the legacy et-cat rules --- REGRESSION.md | 11 +++++++++-- .../rules.d/{100-et-lora.rules => 76-et-lora.rules} | 0 2 files changed, 9 insertions(+), 2 deletions(-) rename overlay/etc/udev/rules.d/{100-et-lora.rules => 76-et-lora.rules} (100%) diff --git a/REGRESSION.md b/REGRESSION.md index c02fd8d..c492a5e 100644 --- a/REGRESSION.md +++ b/REGRESSION.md @@ -1,7 +1,7 @@ # ETC Regression Tests -- **Build**: ETC R7 Build 3 -- **Date**: 12 May 2026 +- **Build**: ETC R7 Build 5 +- **Date**: 14 June 2026 ## Desktop/Launcher Icons @@ -142,3 +142,10 @@ * [ ] `offline` folder on Desktop * [ ] Check `nets` folder for `amrron` and `ghostnet` * [ ] Test gpg signature verifcation (see gpg crypto doc) + +## LoRa + +* [ ] SDR and LoRa listed in Conky +* [ ] Heltec v3 and DigiRig Lite (chip sets conflict) +* [ ] Heltec v4 + diff --git a/overlay/etc/udev/rules.d/100-et-lora.rules b/overlay/etc/udev/rules.d/76-et-lora.rules similarity index 100% rename from overlay/etc/udev/rules.d/100-et-lora.rules rename to overlay/etc/udev/rules.d/76-et-lora.rules From 4b60b56f71bf6a43091179048f1c5129de6afba0 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 14 Jun 2026 15:32:06 -0700 Subject: [PATCH 22/64] lora - Added support for LilyGO TTGO v2.1 and disabled Heltec v3 --- overlay/etc/udev/rules.d/76-et-lora.rules | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/overlay/etc/udev/rules.d/76-et-lora.rules b/overlay/etc/udev/rules.d/76-et-lora.rules index aa3c398..4b98d43 100644 --- a/overlay/etc/udev/rules.d/76-et-lora.rules +++ b/overlay/etc/udev/rules.d/76-et-lora.rules @@ -4,6 +4,8 @@ # # Supported Devices # 1. Heltec v4 +# 2. Heltec v3 (disabled due to collection with et-radio devices) +# 3. LilyGO TTGO v2.1 # # Preconditions: # 1. LoRa device connected via USB cable @@ -16,11 +18,13 @@ # Heltec v4 SUBSYSTEM=="usb", ATTRS{idVendor}=="303a", ATTRS{idProduct}=="1001", \ - GROUP="dialout", MODE="0660", SYMLINK+="et-lora" - + ENV{ET_SUBDEVICE}="LORA" GROUP="dialout", MODE="0660", SYMLINK+="et-lora" # Heltec v3 # Uses the CP210x so this will collide with radios already supported by et-radio -SUBSYSTEM=="usb", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", \ - GROUP="dialout", MODE="0660", SYMLINK+="et-lora" +#SUBSYSTEM=="usb", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", \ +# GROUP="dialout", MODE="0660", SYMLINK+="et-lora" +# LilyGO TTGO v2.1 +SUBSYSTEM=="usb", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d4", \ + ENV{ET_SUBDEVICE}="LORA" GROUP="dialout", MODE="0660", SYMLINK+="et-lora" From 8009e03284a4aa36f54fe55da53a0aa9e9edd1aa Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 14 Jun 2026 15:49:00 -0700 Subject: [PATCH 23/64] reticulum - Initial proof-of-concept for supporting multiple Reticulum configurations. EmComm Tools refers to these as 'Blueprints'. --- ...ig => config.blueprint.local-network-only} | 15 +- .../config.blueprint.permanent-transport-node | 8 +- .../config.blueprint.radio-only-node | 135 ++++++++++++++++++ 3 files changed, 145 insertions(+), 13 deletions(-) rename overlay/etc/skel/.reticulum/{config => config.blueprint.local-network-only} (91%) create mode 100644 overlay/etc/skel/.reticulum/config.blueprint.radio-only-node diff --git a/overlay/etc/skel/.reticulum/config b/overlay/etc/skel/.reticulum/config.blueprint.local-network-only similarity index 91% rename from overlay/etc/skel/.reticulum/config rename to overlay/etc/skel/.reticulum/config.blueprint.local-network-only index e0e6a83..bef0286 100644 --- a/overlay/etc/skel/.reticulum/config +++ b/overlay/etc/skel/.reticulum/config.blueprint.local-network-only @@ -1,12 +1,9 @@ -# This is the default Reticulum config file. -# You should probably edit it to include any additional, -# interfaces and settings you might need. - -# Only the most basic options are included in this default -# configuration. To see a more verbose, and much longer, -# configuration example, you can run the command: -# rnsd --exampleconfig - +# Author : Gaston Gonzalez +# Date : 14 June 2026 +# Blueprint : Local network only +# Purpose : This configuration is a blueprint for running a node that +# only interacts with other nodes on the local Ethernet or +# Wi-Fi. [reticulum] diff --git a/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node b/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node index d781d0e..702d944 100644 --- a/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node +++ b/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node @@ -1,10 +1,9 @@ # Author : Gaston Gonzalez # Date : 7 June 2026 -# Updated : 7 June 2026 +# Updated : 14 June 2026 # Blueprint : Permament Transport Node -# Purpose : This coniguration is a blueprint (i.e. reference -# configuration) for running a 24x7 transport -# Reticulum node with multiple interfaces. +# Purpose : This configuration is a blueprint for running a node that +# as 24x7 transport node with multiple interfaces. [reticulum] @@ -87,6 +86,7 @@ [[Packet Radio AX.25 KISS]] type = AX25KISSInterface + mode = ap enabled = {{ET_RETICULUM_INTERFACE_AX25KISS_ENABLED}} callsign = {{ET_CALLSIGN}} diff --git a/overlay/etc/skel/.reticulum/config.blueprint.radio-only-node b/overlay/etc/skel/.reticulum/config.blueprint.radio-only-node new file mode 100644 index 0000000..aada4b7 --- /dev/null +++ b/overlay/etc/skel/.reticulum/config.blueprint.radio-only-node @@ -0,0 +1,135 @@ +# Author : Gaston Gonzalez +# Date : 7 June 2026 +# Updated : 14 June 2026 +# Blueprint : Permament Transport Node +# Purpose : This confguration is a blueprint for a radio-only node. +# If a supported et-radio and/or et-lora device is +# detected, they will be enabled. + +[reticulum] + + # If you enable Transport, your system will route traffic + # for other peers, pass announces and serve path requests. + # This should only be done for systems that are suited to + # act as transport nodes, ie. if they are stationary and + # always-on. This directive is optional and can be removed + # for brevity. + + enable_transport = False + + + # By default, the first program to launch the Reticulum + # Network Stack will create a shared instance, that other + # programs can communicate with. Only the shared instance + # opens all the configured interfaces directly, and other + # local programs communicate with the shared instance over + # a local socket. This is completely transparent to the + # user, and should generally be turned on. This directive + # is optional and can be removed for brevity. + + share_instance = Yes + + + # If you want to run multiple *different* shared instances + # on the same system, you will need to specify different + # instance names for each. On platforms supporting domain + # sockets, this can be done with the instance_name option: + + instance_name = default + +# You can configure whether Reticulum should discover +# available interfaces from other Transport Instances over +# the network. If this option is enabled, Reticulum will +# collect interface information discovered from the network. + +# discover_interfaces = No + + +# You can configure Reticulum to panic and forcibly close +# if an unrecoverable interface error occurs, such as the +# hardware device for an interface disappearing. This is +# an optional directive, and can be left out for brevity. +# This behaviour is disabled by default. + +# panic_on_interface_error = No + + +# If you're connecting to a large external network, you +# can use one or more external blackhole list to block +# spammy and excessive announces onto your network. This +# funtionality is especially useful if you're hosting public +# entrypoints or gateways. The list source below provides a +# functional example, but better, more timely maintained +# lists probably exist in the community. + +# blackhole_sources = 521c87a83afb8f29e4455e77930b973b + + +[logging] + # Valid log levels are 0 through 7: + # 0: Log only critical information + # 1: Log errors and lower log levels + # 2: Log warnings and lower log levels + # 3: Log notices and lower log levels + # 4: Log info and lower (this is the default) + # 5: Verbose logging + # 6: Debug logging + # 7: Extreme logging + + loglevel = 4 + + +[interfaces] + + [[Default Interface]] + type = AutoInterface + enabled = No + + [[Packet Radio AX.25 KISS]] + type = AX25KISSInterface + mode = roaming + enabled = {{ET_RETICULUM_INTERFACE_AX25KISS_ENABLED}} + + callsign = {{ET_CALLSIGN}} + ssid = 1 + + port = /tmp/kisstnc + mtu = 256 + + [[RNode LoRa Interface]] + type = RNodeInterface + mode = roaming + enabled = {{ET_RETICULUM_INTERFACE_RNODE_ENABLED}} + + port = /dev/et-lora + + # Set frequency to 915 MHz + frequency = 915000000 + #frequency = {{ET_RETICULUM_INTERFACE_RNODE_FREQUENCY}} + + # Set LoRa bandwidth to 125 KHz + bandwidth = 125000 + #bandwidth = {{ET_RETICULUM_INTERFACE_RNODE_BANDWIDTH}} + + # Set TX power in dBm + # 7 dBm = 5 mW + # 17 dbm = 50 mW + # 20 dbm = 100 mW + # 22 dbm = 158 mW + # 28 dbm = 631 mW + # 30 dbm = 1 wat + txpower = 22 + #txpower = {{ET_RETICULUM_INTERFACE_RNODE_TXPOWER}} + + # Select spreading factor 8. Valid + # range is 7 through 12, with 7 + # being the fastest and 12 having + # the longest range. + spreadingfactor = 9 + #spreadingfactor = {{ET_RETICULUM_INTERFACE_RNODE_SPREADINGFACTOR}} + + # Select coding rate 5. Valid range + # is 5 throough 8, with 5 being the + # fastest, and 8 the longest range. + codingrate = 5 + #codingrate = {{ET_RETICULUM_INTERFACE_RNODE_CODINGRATE}} From 25cd53e68afa70d05af28d331b243751fb79e2e1 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 14 Jun 2026 15:53:41 -0700 Subject: [PATCH 24/64] reticulum - Removing initial attempt add managing Reticulum configuration files in EmComm Tools --- .../template.d/reticulum/config.ax25.1200 | 162 ------------------ .../conf/template.d/reticulum/config.ax25.300 | 128 -------------- 2 files changed, 290 deletions(-) delete mode 100644 overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.1200 delete mode 100644 overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.300 diff --git a/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.1200 b/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.1200 deleted file mode 100644 index b574109..0000000 --- a/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.1200 +++ /dev/null @@ -1,162 +0,0 @@ -# This is the default Reticulum config file. -# You should probably edit it to include any additional, -# interfaces and settings you might need. - -# Only the most basic options are included in this default -# configuration. To see a more verbose, and much longer, -# configuration example, you can run the command: -# rnsd --exampleconfig - - -[reticulum] - - # If you enable Transport, your system will route traffic - # for other peers, pass announces and serve path requests. - # This should only be done for systems that are suited to - # act as transport nodes, ie. if they are stationary and - # always-on. This directive is optional and can be removed - # for brevity. - - enable_transport = True - - - # By default, the first program to launch the Reticulum - # Network Stack will create a shared instance, that other - # programs can communicate with. Only the shared instance - # opens all the configured interfaces directly, and other - # local programs communicate with the shared instance over - # a local socket. This is completely transparent to the - # user, and should generally be turned on. This directive - # is optional and can be removed for brevity. - - share_instance = Yes - - - # If you want to run multiple *different* shared instances - # on the same system, you will need to specify different - # instance names for each. On platforms supporting domain - # sockets, this can be done with the instance_name option: - - instance_name = default - - -# Some platforms don't support domain sockets, and if that -# is the case, you can isolate different instances by -# specifying a unique set of ports for each: - -# shared_instance_port = 37428 -# instance_control_port = 37429 - - -# If you want to explicitly use TCP for shared instance -# communication, instead of domain sockets, this is also -# possible, by using the following option: - -# shared_instance_type = tcp - - -# You can configure whether Reticulum should discover -# available interfaces from other Transport Instances over -# the network. If this option is enabled, Reticulum will -# collect interface information discovered from the network. - -# discover_interfaces = No - - -# You can configure Reticulum to panic and forcibly close -# if an unrecoverable interface error occurs, such as the -# hardware device for an interface disappearing. This is -# an optional directive, and can be left out for brevity. -# This behaviour is disabled by default. - -# panic_on_interface_error = No - - -# If you're connecting to a large external network, you -# can use one or more external blackhole list to block -# spammy and excessive announces onto your network. This -# funtionality is especially useful if you're hosting public -# entrypoints or gateways. The list source below provides a -# functional example, but better, more timely maintained -# lists probably exist in the community. - -# blackhole_sources = 521c87a83afb8f29e4455e77930b973b - - -[logging] - # Valid log levels are 0 through 7: - # 0: Log only critical information - # 1: Log errors and lower log levels - # 2: Log warnings and lower log levels - # 3: Log notices and lower log levels - # 4: Log info and lower (this is the default) - # 5: Verbose logging - # 6: Debug logging - # 7: Extreme logging - - loglevel = 4 - - -# The interfaces section defines the physical and virtual -# interfaces Reticulum will use to communicate on. This -# section will contain examples for a variety of interface -# types. You can modify these or use them as a basis for -# your own config, or simply remove the unused ones. - -[interfaces] - - # This interface enables communication with other - # link-local Reticulum nodes over UDP. It does not - # need any functional IP infrastructure like routers - # or DHCP servers, but will require that at least link- - # local IPv6 is enabled in your operating system, which - # should be enabled by default in almost any OS. See - # the Reticulum Manual for more configuration options. - - [[Default Interface]] - type = AutoInterface - enabled = Yes - - [[Packet Radio AX25 KISS]] - type = AX25KISSInterface - enabled = Yes - - callsign = {{ET_CALLSIGN}} - ssid = 1 - - port = /tmp/kisstnc - mtu = 256 - - [[RNode LoRa Interface]] - type = RNodeInterface - enabled = yes - - # Connect via Wi-Fi - port = tcp://192.168.8.167 - -# # Add PnP support: /dev/et-lora -# port = /dev/ttyACM1 - - - # Set frequency to 915 MHz - frequency = 915000000 - - # Set LoRa bandwidth to 125 KHz - bandwidth = 125000 - - # Set TX power in dBm - # 7 dBm = 5 mW - # 17 dbm = - # 22 dbm = - txpower = 17 - - # Select spreading factor 8. Valid - # range is 7 through 12, with 7 - # being the fastest and 12 having - # the longest range. - spreadingfactor = 9 - - # Select coding rate 5. Valid range - # is 5 throough 8, with 5 being the - # fastest, and 8 the longest range. - codingrate = 5 diff --git a/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.300 b/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.300 deleted file mode 100644 index dc51934..0000000 --- a/overlay/opt/emcomm-tools/conf/template.d/reticulum/config.ax25.300 +++ /dev/null @@ -1,128 +0,0 @@ -# This is the default Reticulum config file. -# You should probably edit it to include any additional, -# interfaces and settings you might need. - -# Only the most basic options are included in this default -# configuration. To see a more verbose, and much longer, -# configuration example, you can run the command: -# rnsd --exampleconfig - - -[reticulum] - - # If you enable Transport, your system will route traffic - # for other peers, pass announces and serve path requests. - # This should only be done for systems that are suited to - # act as transport nodes, ie. if they are stationary and - # always-on. This directive is optional and can be removed - # for brevity. - - enable_transport = True - - - # By default, the first program to launch the Reticulum - # Network Stack will create a shared instance, that other - # programs can communicate with. Only the shared instance - # opens all the configured interfaces directly, and other - # local programs communicate with the shared instance over - # a local socket. This is completely transparent to the - # user, and should generally be turned on. This directive - # is optional and can be removed for brevity. - - share_instance = Yes - - - # If you want to run multiple *different* shared instances - # on the same system, you will need to specify different - # instance names for each. On platforms supporting domain - # sockets, this can be done with the instance_name option: - - instance_name = default - - -# Some platforms don't support domain sockets, and if that -# is the case, you can isolate different instances by -# specifying a unique set of ports for each: - -# shared_instance_port = 37428 -# instance_control_port = 37429 - - -# If you want to explicitly use TCP for shared instance -# communication, instead of domain sockets, this is also -# possible, by using the following option: - -# shared_instance_type = tcp - - -# You can configure whether Reticulum should discover -# available interfaces from other Transport Instances over -# the network. If this option is enabled, Reticulum will -# collect interface information discovered from the network. - -# discover_interfaces = No - - -# You can configure Reticulum to panic and forcibly close -# if an unrecoverable interface error occurs, such as the -# hardware device for an interface disappearing. This is -# an optional directive, and can be left out for brevity. -# This behaviour is disabled by default. - -# panic_on_interface_error = No - - -# If you're connecting to a large external network, you -# can use one or more external blackhole list to block -# spammy and excessive announces onto your network. This -# funtionality is especially useful if you're hosting public -# entrypoints or gateways. The list source below provides a -# functional example, but better, more timely maintained -# lists probably exist in the community. - -# blackhole_sources = 521c87a83afb8f29e4455e77930b973b - - -[logging] - # Valid log levels are 0 through 7: - # 0: Log only critical information - # 1: Log errors and lower log levels - # 2: Log warnings and lower log levels - # 3: Log notices and lower log levels - # 4: Log info and lower (this is the default) - # 5: Verbose logging - # 6: Debug logging - # 7: Extreme logging - - loglevel = 4 - - -# The interfaces section defines the physical and virtual -# interfaces Reticulum will use to communicate on. This -# section will contain examples for a variety of interface -# types. You can modify these or use them as a basis for -# your own config, or simply remove the unused ones. - -[interfaces] - - # This interface enables communication with other - # link-local Reticulum nodes over UDP. It does not - # need any functional IP infrastructure like routers - # or DHCP servers, but will require that at least link- - # local IPv6 is enabled in your operating system, which - # should be enabled by default in almost any OS. See - # the Reticulum Manual for more configuration options. - - [[Default Interface]] - type = AutoInterface - enabled = Yes - - [[Packet Radio AX25 KISS]] - type = AX25KISSInterface - enabled = Yes - - callsign = {{ET_CALLSIGN}} - ssid = 1 - - port = /tmp/kisstnc - mtu = 256 From 26b0c0b556169a6b304326dd11f7c789e4827a13 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 14 Jun 2026 18:02:28 -0700 Subject: [PATCH 25/64] reticulum - Complete redesign for starting the Reticulum Network Stack. Still a work in progress. --- overlay/opt/emcomm-tools/bin/et-reticulum | 162 ++++++++-------------- 1 file changed, 55 insertions(+), 107 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum index d5c94bc..e482b16 100755 --- a/overlay/opt/emcomm-tools/bin/et-reticulum +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 12 May 2026 -# Updated : 13 May 2026 +# Updated : 14 May 2026 # Purpose : Wrapper script for starting Reticulum with PnP support # # Preconditions: @@ -10,7 +10,7 @@ # # Postconditions: # 1. Reticulum configuration updated -# 2. Dire Wolf started +# 2. Optional modem started # 3. Reticulum started . /opt/emcomm-tools/bin/et-common @@ -18,122 +18,70 @@ APP="Reticulum" RETICULUM_CONF_DIR="${HOME}/.reticulum" RETICULUM_CONF_FILE="${RETICULUM_CONF_DIR}/config" -usage() { - echo "usage: $(basename $0) " - echo " " - echo " start - Start ${APP} in selected mode" - echo " update-config - Update configuration for selected mode" - echo "" - echo " " - echo " 1200 - Run with AX.25 interface over VHF/UHF (1200 baud)" - echo " 300 - Run with AX.25 interface over HF (300 baud)" -} +options=() +files=() +index=1 -if [ $# -ne 2 ]; then - usage - exit 1 +while IFS= read -r file; do + name=$(basename "$file") + files[$index]="$name" + options+=("$index" "$name") + ((index++)) +done < <(find "${HOME}/.reticulum" -type f -name 'config.blueprint.*') + +choice=$(dialog \ + --title "Reticulum Configuration" \ + --menu "Choose a blueprint:" \ + 15 60 10 \ + "${options[@]}" \ + 2>&1 >/dev/tty) +EXIT_STATUS=$? + +tput sgr0 && clear + +if [[ ${EXIT_STATUS} -ne 0 ]]; then + et-log "No blueprint configuration selected" + exit ${EXIT_STATUS} fi -MODE=$2 -case "${MODE}" in - 1200) - RETICULUM_TEMPLATE_CONF_FILE="${ET_HOME}/conf/template.d/reticulum/config.ax25.1200" - RETICULUM_PACKET_INTERFACE_SERVICE=et-service-direwolf-simple - ;; - 300) - RETICULUM_TEMPLATE_CONF_FILE="${ET_HOME}/conf/template.d/reticulum/config.ax25.300" - RETICULUM_PACKET_INTERFACE_SERVICE=et-service-direwolf-300 - ;; - *) - et-log "Can't start ${APP}. Mode '${MODE}' not supported" - usage - exit 1 - ;; -esac +SELECTED_CONF="${files[$choice]}" if [[ ! -e "${RETICULUM_CONF_DIR}" ]]; then - et-log "Creating missing configuration directory: ${RETICULUM_CONF_DIR}" - mkdir -p "${RETICULUM_CONF_DIR}" + et-log "Creating missing configuration directory: ${RETICULUM_CONF_DIR}" + mkdir -p "${RETICULUM_CONF_DIR}" fi -if [[ ! -e "${RETICULUM_TEMPLATE_CONF_FILE}" ]]; then - et-log "${RETICULUM_TEMPLATE_CONF_FILE} does not exist. Exiting." - notify-user "Config file does not exist. Can't start Reticulum." +ACTIVE_CONF_FILE="${RETICULUM_CONF_DIR}/${SELECTED_CONF}" +if [[ ! -e ${ACTIVE_CONF_FILE} ]]; then + et-log "${ACTIVE_CONF_FILE} does not exist." exit 1 fi -start() { - update_config - - if [[ $? -eq 0 ]]; then +et-log "Using ${ACTIVE_CONF_FILE}" - systemctl is-active --quiet ${RETICULUM_PACKET_INTERFACE_SERVICE} - if [[ $? -ne 0 ]]; then - start_and_wait_for_service ${RETICULUM_PACKET_INTERFACE_SERVICE} - fi - - CMD="rnsd" - et-log "Starting ${APP} with: '${CMD}'" - echo - ${CMD} - else - et-log "Error updating configuration. Can't start ${APP}" - exit 1 - fi -} +if [[ -e "${RETICULUM_CONF_FILE}" ]]; then + et-log "Removing previous Reticulum configuration: ${RETICULUM_CONF_FILE}" + rm "${RETICULUM_CONF_FILE}" +fi + +et-log "Linking new configuration..." +ln -v -s "${ACTIVE_CONF_FILE}" "${RETICULUM_CONF_FILE}" + +# Update replacement tokens + +# Callsign +[[ -z "$ET_USER_CONFIG" ]] && ET_USER_CONFIG="${HOME}/.config/emcomm-tools/user.json" +CALLSIGN=$(cat ${ET_USER_CONFIG} | jq -r .callsign) +sed -i "s|{{ET_CALLSIGN}}|${CALLSIGN}|g" ${RETICULUM_CONF_FILE} + +# AX.25 KISS interface +sed -i "s|{{ET_RETICULUM_INTERFACE_AX25KISS_ENABLED}}|no|g" ${RETICULUM_CONF_FILE} + +# RNode (LoRA) interface +sed -i "s|{{ET_RETICULUM_INTERFACE_RNODE_ENABLED}}|yes|g" ${RETICULUM_CONF_FILE} -update_config () { +CMD="rnsd" +et-log "Starting Reticulum: ${CMD}" - et-log "Attempting to start ${APP} in mode: '${MODE}'" - - [[ -z "$ET_USER_CONFIG" ]] && ET_USER_CONFIG="${HOME}/.config/emcomm-tools/user.json" - - CALLSIGN=$(cat ${ET_USER_CONFIG} | jq -r .callsign) - - if [[ "${CALLSIGN}" = "N0CALL" ]]; then - notify_user "Can't ${APP}. No callsign set. Run: et-user." - exit 1 - fi - - # 1. Check if the audio symlink was created by the udev rules - if [[ -e /dev/et-audio ]]; then - - # Check that this device was properly tagged with the ET_AUDIO env variable with a udev rule - APLAY_OUT=$(arecord -l | grep ET_AUDIO) - if [[ $? -eq 0 ]]; then - - # Configure ALSA settings for sound card - /opt/emcomm-tools/bin/et-audio update-config - - else - et-log "No ET_AUDIO device detected." - notify-user "Can't start ${APP}. No ET_AUDIO device detected." - exit 1 - fi - else - et-log "No ET_AUDIO device plugged in." - notify-user "Can't start ${APP}. No supported audio device plugged in." - exit 1 - fi - - et-log "Creating '${RETICULUM_CONF_FILE}' from template '${RETICULUM_TEMPLATE_CONF_FILE}'" - cp ${RETICULUM_TEMPLATE_CONF_FILE} ${RETICULUM_CONF_FILE} - - # Update callsign - sed -i "s|{{ET_CALLSIGN}}|${CALLSIGN}|g" ${RETICULUM_CONF_FILE} -} - -case $1 in - start) - start - ;; - update-config) - update_config - ;; - *) - echo "Invalid command." - usage - exit 1 - ;; -esac +${CMD} From 510657d1c9ba073ceab939582b9752f0ef24ff98 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 14 Jun 2026 18:13:54 -0700 Subject: [PATCH 26/64] lora - Updated LoRa udev rules to correctly create a symlink to /dev --- overlay/etc/udev/rules.d/76-et-lora.rules | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/overlay/etc/udev/rules.d/76-et-lora.rules b/overlay/etc/udev/rules.d/76-et-lora.rules index 4b98d43..1a8c6b7 100644 --- a/overlay/etc/udev/rules.d/76-et-lora.rules +++ b/overlay/etc/udev/rules.d/76-et-lora.rules @@ -13,12 +13,10 @@ # Postconditions: # 1. /dev/et-lora created -#KERNEL=="swradio0", \ -# GROUP="dialout", MODE="0660", SYMLINK+="et-sdr" - # Heltec v4 -SUBSYSTEM=="usb", ATTRS{idVendor}=="303a", ATTRS{idProduct}=="1001", \ - ENV{ET_SUBDEVICE}="LORA" GROUP="dialout", MODE="0660", SYMLINK+="et-lora" +SUBSYSTEM=="tty", ATTRS{idVendor}=="303a", ATTRS{idProduct}=="1001", ENV{ET_LORA_DEVICE}=="" \ + ACTION=="add", \ + ENV{ET_LORA_DEVICE}="Heltec v4" GROUP="dialout", MODE="0660", SYMLINK+="et-lora" # Heltec v3 # Uses the CP210x so this will collide with radios already supported by et-radio @@ -26,5 +24,6 @@ SUBSYSTEM=="usb", ATTRS{idVendor}=="303a", ATTRS{idProduct}=="1001", \ # GROUP="dialout", MODE="0660", SYMLINK+="et-lora" # LilyGO TTGO v2.1 -SUBSYSTEM=="usb", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d4", \ - ENV{ET_SUBDEVICE}="LORA" GROUP="dialout", MODE="0660", SYMLINK+="et-lora" +SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d4", ENV{ET_LORA_DEVICE}=="" \ + ACTION=="add", \ + ENV{ET_LORA_DEVICE}="LillyGO TTGO v2.1" GROUP="dialout", MODE="0660", SYMLINK+="et-lora" From d3d5dfcd51796ce299dfc560e455843a09990336 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 14 Jun 2026 18:24:55 -0700 Subject: [PATCH 27/64] reticulum - Added support to dynamically enable the RNode interface if the PnP subsystem detected the device --- .../.reticulum/config.blueprint.radio-only-node | 2 +- overlay/opt/emcomm-tools/bin/et-reticulum | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/overlay/etc/skel/.reticulum/config.blueprint.radio-only-node b/overlay/etc/skel/.reticulum/config.blueprint.radio-only-node index aada4b7..01bee0e 100644 --- a/overlay/etc/skel/.reticulum/config.blueprint.radio-only-node +++ b/overlay/etc/skel/.reticulum/config.blueprint.radio-only-node @@ -117,7 +117,7 @@ # 20 dbm = 100 mW # 22 dbm = 158 mW # 28 dbm = 631 mW - # 30 dbm = 1 wat + # 30 dbm = 1 watt txpower = 22 #txpower = {{ET_RETICULUM_INTERFACE_RNODE_TXPOWER}} diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum index e482b16..de22541 100755 --- a/overlay/opt/emcomm-tools/bin/et-reticulum +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -67,18 +67,22 @@ fi et-log "Linking new configuration..." ln -v -s "${ACTIVE_CONF_FILE}" "${RETICULUM_CONF_FILE}" -# Update replacement tokens -# Callsign +# AX.25 KISS interface updates [[ -z "$ET_USER_CONFIG" ]] && ET_USER_CONFIG="${HOME}/.config/emcomm-tools/user.json" CALLSIGN=$(cat ${ET_USER_CONFIG} | jq -r .callsign) sed -i "s|{{ET_CALLSIGN}}|${CALLSIGN}|g" ${RETICULUM_CONF_FILE} -# AX.25 KISS interface sed -i "s|{{ET_RETICULUM_INTERFACE_AX25KISS_ENABLED}}|no|g" ${RETICULUM_CONF_FILE} -# RNode (LoRA) interface -sed -i "s|{{ET_RETICULUM_INTERFACE_RNODE_ENABLED}}|yes|g" ${RETICULUM_CONF_FILE} +# RNode (LoRA) interface updates +if [[ -e /dev/et-lora ]]; then + INTERFACE_RNODE_ENABLED="yes" +else + INTERFACE_RNODE_ENABLED="no" +fi + +sed -i "s|{{ET_RETICULUM_INTERFACE_RNODE_ENABLED}}|${INTERFACE_RNODE_ENABLED}|g" ${RETICULUM_CONF_FILE} CMD="rnsd" From 9467576a837a194a27985380dfe72dae3b682553 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 14 Jun 2026 18:35:14 -0700 Subject: [PATCH 28/64] reticulum - Added support to dynamically enable the AX.25 interface if the PnP subsystem detected the device --- overlay/opt/emcomm-tools/bin/et-reticulum | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum index de22541..15a3e85 100755 --- a/overlay/opt/emcomm-tools/bin/et-reticulum +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -68,14 +68,31 @@ et-log "Linking new configuration..." ln -v -s "${ACTIVE_CONF_FILE}" "${RETICULUM_CONF_FILE}" -# AX.25 KISS interface updates +et-log "Updating configuration for this session..." + +############################################################ +# AX.25 KISS (Packet Radio) interface updates +############################################################ + +# Enable/disable intereface based on PnP device detection +if [[ -e /tmp/kisstnc ]]; then + INTERFACE_AX25KISS_ENABLED="yes" +else + INTERFACE_AX25KISS_ENABLED="no" +fi +sed -i "s|{{ET_RETICULUM_INTERFACE_AX25KISS_ENABLED}}|${INTERFACE_AX25KISS_ENABLED}|g" ${RETICULUM_CONF_FILE} + +# Update callsign [[ -z "$ET_USER_CONFIG" ]] && ET_USER_CONFIG="${HOME}/.config/emcomm-tools/user.json" CALLSIGN=$(cat ${ET_USER_CONFIG} | jq -r .callsign) sed -i "s|{{ET_CALLSIGN}}|${CALLSIGN}|g" ${RETICULUM_CONF_FILE} -sed -i "s|{{ET_RETICULUM_INTERFACE_AX25KISS_ENABLED}}|no|g" ${RETICULUM_CONF_FILE} +############################################################ # RNode (LoRA) interface updates +############################################################ + +# Enable/disable intereface based on PnP device detection if [[ -e /dev/et-lora ]]; then INTERFACE_RNODE_ENABLED="yes" else From d614e5c9cc6132605d4733c6c38f6e343041f409 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 14 Jun 2026 18:40:15 -0700 Subject: [PATCH 29/64] et-mode - Removed Reticulum as an option --- overlay/opt/emcomm-tools/bin/et-mode | 57 +--------------------------- 1 file changed, 1 insertion(+), 56 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-mode b/overlay/opt/emcomm-tools/bin/et-mode index 507525c..be31cff 100755 --- a/overlay/opt/emcomm-tools/bin/et-mode +++ b/overlay/opt/emcomm-tools/bin/et-mode @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 6 November 2024 -# Updated : 13 May 2026 +# Updated : 14 June 2026 # Purpose : Configures the system for a specific mode of operation # Use a simple text file to save the state of the last mode selected @@ -19,8 +19,6 @@ MODE_ID_BBS_CLIENT2="bbs-client2" MODE_ID_BBS_SERVER="bbs-server" MODE_ID_CHAT_CLIENT="chat-chattervox" MODE_ID_PACKET_DIGIPEATER="packet-digipeater" -MODE_ID_RETICULUM_MESHCHAT="reticulum-meshchat" -MODE_ID_RETICULUM_NOMADNET="reticulum-nomadnet" MODE_ID_WINLINK_ARDOP="winlink-ardop" MODE_ID_WINLINK_PACKET="winlink-packet" MODE_ID_WINLINK_VARA_HF="winlink-vara-hf" @@ -131,27 +129,6 @@ select_term_mode () { fi } -select_reticulum_mode () { - term_mode=() - term_mode+=("1200" "1200 baud (default for VHF/UHF)") - term_mode+=("300" "300 baud (HF)") - - TERM_MODE=$(dialog --clear --menu "Select a modem" 13 60 10 "${term_mode[@]}" 3>&1 1>&2 2>&3) - - dialog \ - --title "Note on Reticulum" \ - --yesno "Reticulum uses end-to-end encryption. Check your local laws and regulations and ensure that you can legally run this mode!" \ - 0 0 - exit_status=$? - - tput sgr 0 && clear - - if [ ${exit_status} -ne 0 ]; then - et-log "User canceled mode selection. Mode will not be started." - exit 1 - fi -} - wwv_mode () { dialog --title "Note on WWV" --msgbox "Manually set your radio to AM and tune it to one of the WWV frequencies appropriate for this operating time.\n\nTry: 2.5, 5, 10, 15 or 20 MHz." 0 0 tput sgr 0 && clear @@ -180,8 +157,6 @@ if [ -e "${HOME}/.wine32/drive_c/VARA/VARA.exe" ]; then fi options+=("${MODE_ID_TIME_WWV}" "Sync clock to WWV") -options+=("${MODE_ID_RETICULUM_MESHCHAT}" "Reticulum MeshChat over AX.25 Packet") -options+=("${MODE_ID_RETICULUM_NOMADNET}" "Reticulum NomadNet over AX.25 Packet") # Prompt user for option and save exit status SELECTED_MODE=$(dialog --clear --menu "Select a mode:" 18 65 10 "${options[@]}" 3>&1 1>&2 2>&3) @@ -300,36 +275,6 @@ if [ $exit_status -eq 0 ]; then wwv_mode sudo /opt/emcomm-tools/sbin/wrapper-et-wwv.sh ;; - ${MODE_ID_RETICULUM_MESHCHAT}) - select_reticulum_mode - et-log "Using ${TERM_MODE} as the modem." - - case "${TERM_MODE}" in - "1200") - start_and_wait_for_service et-service-reticulum-1200 - ;; - "300") - start_and_wait_for_service et-service-reticulum-300 - ;; - esac - - et-meshchat - ;; - ${MODE_ID_RETICULUM_NOMADNET}) - select_reticulum_mode - et-log "Using ${TERM_MODE} as the modem." - - case "${TERM_MODE}" in - "1200") - start_and_wait_for_service et-service-reticulum-1200 - ;; - "300") - start_and_wait_for_service et-service-reticulum-300 - ;; - esac - - nomadnet - ;; *) et-log "Mode ${SELECTED_MODE} not yet supported" exit 1 From 941b747dba34c9f822f66bb35021689e34617c83 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 14 Jun 2026 18:42:39 -0700 Subject: [PATCH 30/64] reticulum - Removed original approach for Reticulum systemd services --- .../user/et-service-reticulum-1200.service | 20 ------------------- .../user/et-service-reticulum-300.service | 20 ------------------- 2 files changed, 40 deletions(-) delete mode 100644 overlay/etc/skel/.config/systemd/user/et-service-reticulum-1200.service delete mode 100644 overlay/etc/skel/.config/systemd/user/et-service-reticulum-300.service diff --git a/overlay/etc/skel/.config/systemd/user/et-service-reticulum-1200.service b/overlay/etc/skel/.config/systemd/user/et-service-reticulum-1200.service deleted file mode 100644 index d721934..0000000 --- a/overlay/etc/skel/.config/systemd/user/et-service-reticulum-1200.service +++ /dev/null @@ -1,20 +0,0 @@ -# Author : Gaston Gonzalez -# Date : 12 May 2026 -# Purpose : User systemd unit file for EmComm Tools Reticulum 1200 baud -# : packet service. -# -# Usage: -# Check status : systemctl --user status et-service-reticulum-1200 -# Start service : systemctl --user start et-service-reticulum-1200 -# Stop service : systemctl --user stop et-service-reticulum-1200 -# Reload this config : systemctl --user daemon-reload - -[Unit] -Description=EmComm Tools Reticulum 1200 baud packet service - -[Service] -ExecStart=/opt/emcomm-tools/bin/et-reticulum start 1200 -Restart=no - -[Install] -WantedBy=multi-user.target diff --git a/overlay/etc/skel/.config/systemd/user/et-service-reticulum-300.service b/overlay/etc/skel/.config/systemd/user/et-service-reticulum-300.service deleted file mode 100644 index fa1e79a..0000000 --- a/overlay/etc/skel/.config/systemd/user/et-service-reticulum-300.service +++ /dev/null @@ -1,20 +0,0 @@ -# Author : Gaston Gonzalez -# Date : 12 May 2026 -# Purpose : User systemd unit file for EmComm Tools Reticulum 300 baud -# : packet service. -# -# Usage: -# Check status : systemctl --user status et-service-reticulum-300 -# Start service : systemctl --user start et-service-reticulum-300 -# Stop service : systemctl --user stop et-service-reticulum-300 -# Reload this config : systemctl --user daemon-reload - -[Unit] -Description=EmComm Tools Reticulum 300 baud packet service - -[Service] -ExecStart=/opt/emcomm-tools/bin/et-reticulum start 300 -Restart=no - -[Install] -WantedBy=multi-user.target From 8c7c364fd3445cc755818c24308c26acb17c5afa Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 14 Jun 2026 19:26:29 -0700 Subject: [PATCH 31/64] reticulum - Added support for optionally started a packet modem if a supported is plugged in and detected --- overlay/opt/emcomm-tools/bin/et-reticulum | 49 +++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum index 15a3e85..dd574b7 100755 --- a/overlay/opt/emcomm-tools/bin/et-reticulum +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -67,6 +67,55 @@ fi et-log "Linking new configuration..." ln -v -s "${ACTIVE_CONF_FILE}" "${RETICULUM_CONF_FILE}" +############################################################ +# Optionally, launch a modem if a radio is connected +############################################################ + +# If a supported radio is plugged in and detected, it will have the +# rigctld process running automatically. +IS_RADIO_CONNECTED=`ps -ef | grep [r]igctld` +if [[ $? -eq 0 ]]; then + + et-log "Radio connected and detected." + + modem_options=() + modem_options+=("1200" "1200 baud (VHF/UHF operation)") + modem_options+=("300" "300 baud (HF option)") + + modem_choice=$(dialog \ + --clear \ + --title "Reticulum Configuration" \ + --menu "Select a modem" \ + 13 60 10 \ + "${modem_options[@]}" \ + 2>&1 >/dev/tty) + + dialog \ + --title "Note on Reticulum" \ + --yesno "Reticulum uses end-to-end encryption. Check your local laws and regulations and ensure that you can legally run this mode! Are you sure that you want to run this?" \ + 0 0 + EXIT_STATUS=$? + + tput sgr 0 && clear + + if [[ ${EXIT_STATUS} -ne 0 ]]; then + et-log "User canceled modem selection. Packet modem will not be started and interface will not be enabled." + else + case ${modem_choice} in + 300) + et-log "Starting 300 baud packet modem" + start_and_wait_for_service et-service-direwolf-300 + ;; + 1200) + et-log "Starting 1200 baud packet modem" + start_and_wait_for_service et-service-direwolf-simple + ;; + *) + et-log "No modem specified" + ;; + esac + fi +fi et-log "Updating configuration for this session..." From 559bf548faf82f9f5c319557cda07397c5c26093 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 14 Jun 2026 19:29:14 -0700 Subject: [PATCH 32/64] reticulum - Updated regression testing notes --- REGRESSION.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/REGRESSION.md b/REGRESSION.md index c492a5e..420383a 100644 --- a/REGRESSION.md +++ b/REGRESSION.md @@ -145,7 +145,9 @@ ## LoRa -* [ ] SDR and LoRa listed in Conky -* [ ] Heltec v3 and DigiRig Lite (chip sets conflict) -* [ ] Heltec v4 +* [ ] LoRa listed in Conky +* [ ] Heltec v4 PnP +* [ ] et-reticulum + * [ ] All blueprints + * [ ] All permutations of radios and LoRa connected/disconnected From 419d9f8cf6ec9b9167dbeb19e6364f478c3c44d3 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 15 Jun 2026 07:48:32 -0700 Subject: [PATCH 33/64] reticulum - Added initial support for dynamically determining the max TX power output of a device --- .../config.blueprint.permanent-transport-node | 21 +++++++++------- .../config.blueprint.radio-only-node | 24 +++++++++++-------- overlay/opt/emcomm-tools/bin/et-reticulum | 18 +++++++++++--- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node b/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node index 702d944..b53df33 100644 --- a/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node +++ b/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node @@ -109,15 +109,20 @@ # Set LoRa bandwidth to 125 KHz bandwidth = 125000 #bandwidth = {{ET_RETICULUM_INTERFACE_RNODE_BANDWIDTH}} - + # Set TX power in dBm - # 7 dBm = 5 mW - # 17 dbm = 50 mW - # 20 dbm = 100 mW - # 22 dbm = 158 mW - # 28 dbm = 631 mW - txpower = 22 - #txpower = {{ET_RETICULUM_INTERFACE_RNODE_TXPOWER}} + # + # 7 dBm = 5 mW + # 10 dBm = 10 mW + # 14 dBm = 25 mW + # 17 dBm = 50 mW + # 20 dBm = 100 mW + # 22 dBm = 158 mW + # 24 dBm = 251 mW + # 27 dBm = 501 mW + # 28 dBm = 631 mW + # 30 dBm = 1000 mW (1 W) + txpower = {{ET_RETICULUM_INTERFACE_RNODE_TXPOWER}} # Select spreading factor 8. Valid # range is 7 through 12, with 7 diff --git a/overlay/etc/skel/.reticulum/config.blueprint.radio-only-node b/overlay/etc/skel/.reticulum/config.blueprint.radio-only-node index 01bee0e..3917653 100644 --- a/overlay/etc/skel/.reticulum/config.blueprint.radio-only-node +++ b/overlay/etc/skel/.reticulum/config.blueprint.radio-only-node @@ -1,7 +1,7 @@ # Author : Gaston Gonzalez # Date : 7 June 2026 -# Updated : 14 June 2026 -# Blueprint : Permament Transport Node +# Updated : 15 June 2026 +# Blueprint : Radio-Only Node, transport disabled # Purpose : This confguration is a blueprint for a radio-only node. # If a supported et-radio and/or et-lora device is # detected, they will be enabled. @@ -112,14 +112,18 @@ #bandwidth = {{ET_RETICULUM_INTERFACE_RNODE_BANDWIDTH}} # Set TX power in dBm - # 7 dBm = 5 mW - # 17 dbm = 50 mW - # 20 dbm = 100 mW - # 22 dbm = 158 mW - # 28 dbm = 631 mW - # 30 dbm = 1 watt - txpower = 22 - #txpower = {{ET_RETICULUM_INTERFACE_RNODE_TXPOWER}} + # + # 7 dBm = 5 mW + # 10 dBm = 10 mW + # 14 dBm = 25 mW + # 17 dBm = 50 mW + # 20 dBm = 100 mW + # 22 dBm = 158 mW + # 24 dBm = 251 mW + # 27 dBm = 501 mW + # 28 dBm = 631 mW + # 30 dBm = 1000 mW (1 W) + txpower = {{ET_RETICULUM_INTERFACE_RNODE_TXPOWER}} # Select spreading factor 8. Valid # range is 7 through 12, with 7 diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum index dd574b7..8b6b869 100755 --- a/overlay/opt/emcomm-tools/bin/et-reticulum +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 12 May 2026 -# Updated : 14 May 2026 +# Updated : 15 May 2026 # Purpose : Wrapper script for starting Reticulum with PnP support # # Preconditions: @@ -18,6 +18,8 @@ APP="Reticulum" RETICULUM_CONF_DIR="${HOME}/.reticulum" RETICULUM_CONF_FILE="${RETICULUM_CONF_DIR}/config" +INTERFACE_RNODE_TXPOWER_DEFAULT=17 + options=() files=() index=1 @@ -141,15 +143,25 @@ sed -i "s|{{ET_CALLSIGN}}|${CALLSIGN}|g" ${RETICULUM_CONF_FILE} # RNode (LoRA) interface updates ############################################################ -# Enable/disable intereface based on PnP device detection +# 1. Enable/disable intereface based on PnP device detection if [[ -e /dev/et-lora ]]; then INTERFACE_RNODE_ENABLED="yes" else INTERFACE_RNODE_ENABLED="no" fi - sed -i "s|{{ET_RETICULUM_INTERFACE_RNODE_ENABLED}}|${INTERFACE_RNODE_ENABLED}|g" ${RETICULUM_CONF_FILE} +# 2. Determine max power settings +et-log "Connecting to device to determine max power..." +INTERFACE_RNODE_TXPOWER=`rnodeconf -i /dev/et-lora | awk -F': ' '/Max TX power/ {print $2}' | awk '{print $1}'` +if [[ $? -ne 0 ]]; then + INTERFACE_RNODE_TXPOWER=${INTERFACE_RNODE_TXPOWER_DEFAULT} + et-log "Can't determine max power. Using defaulting ${INTERFACE_RNODE_TXPOWER}." +fi + +et-log "Setting max power to ${INTERFACE_RNODE_TXPOWER} dBm." +sed -i "s|{{ET_RETICULUM_INTERFACE_RNODE_TXPOWER}}|${INTERFACE_RNODE_TXPOWER}|g" ${RETICULUM_CONF_FILE} + CMD="rnsd" et-log "Starting Reticulum: ${CMD}" From 87b9216e39ffa90037bd0d9d790cf5a978a3cfc7 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 15 Jun 2026 08:14:44 -0700 Subject: [PATCH 34/64] reticulum - Added ET_DEVICE_LORA to environment --- overlay/opt/emcomm-tools/bin/et-common | 3 ++- overlay/opt/emcomm-tools/bin/et-reticulum | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-common b/overlay/opt/emcomm-tools/bin/et-common index 104e998..7947a30 100755 --- a/overlay/opt/emcomm-tools/bin/et-common +++ b/overlay/opt/emcomm-tools/bin/et-common @@ -1,7 +1,7 @@ #!/bin/bash # Author : Gaston Gonzalez # Date : 1 February 2025 -# Updated : 16 April 2026 +# Updated : 15 June 2026 # Purpose : Common environment variables and functions # Standardized device paths for supported hardware @@ -9,6 +9,7 @@ export ET_DEVICE_AUDIO="/dev/et-audio" export ET_DEVICE_CAT="/dev/et-cat" export ET_DEVICE_GPS="/dev/et-gps" export ET_DEVICE_SDR="/dev/et-sdr" +export ET_DEVICE_LORA="/dev/et-lora" # Standardized configuration locations and files export ET_HOME="/opt/emcomm-tools" diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum index 8b6b869..e48b0ec 100755 --- a/overlay/opt/emcomm-tools/bin/et-reticulum +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -144,7 +144,7 @@ sed -i "s|{{ET_CALLSIGN}}|${CALLSIGN}|g" ${RETICULUM_CONF_FILE} ############################################################ # 1. Enable/disable intereface based on PnP device detection -if [[ -e /dev/et-lora ]]; then +if [[ -e "${ET_DEVICE_LORA}" ]]; then INTERFACE_RNODE_ENABLED="yes" else INTERFACE_RNODE_ENABLED="no" @@ -153,7 +153,7 @@ sed -i "s|{{ET_RETICULUM_INTERFACE_RNODE_ENABLED}}|${INTERFACE_RNODE_ENABLED}|g" # 2. Determine max power settings et-log "Connecting to device to determine max power..." -INTERFACE_RNODE_TXPOWER=`rnodeconf -i /dev/et-lora | awk -F': ' '/Max TX power/ {print $2}' | awk '{print $1}'` +INTERFACE_RNODE_TXPOWER=`rnodeconf -i ${ET_DEVICE_LORA} | awk -F': ' '/Max TX power/ {print $2}' | awk '{print $1}'` if [[ $? -ne 0 ]]; then INTERFACE_RNODE_TXPOWER=${INTERFACE_RNODE_TXPOWER_DEFAULT} et-log "Can't determine max power. Using defaulting ${INTERFACE_RNODE_TXPOWER}." From ae85cbc5348bc2e19f946666e34017cdf72cc469 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 15 Jun 2026 08:22:42 -0700 Subject: [PATCH 35/64] reticulum - Only poll for LoRa power settings if device is detected --- overlay/opt/emcomm-tools/bin/et-reticulum | 27 +++++++++++++---------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum index e48b0ec..f2928fc 100755 --- a/overlay/opt/emcomm-tools/bin/et-reticulum +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -143,25 +143,28 @@ sed -i "s|{{ET_CALLSIGN}}|${CALLSIGN}|g" ${RETICULUM_CONF_FILE} # RNode (LoRA) interface updates ############################################################ -# 1. Enable/disable intereface based on PnP device detection +# Enable/disable intereface based on PnP device detection if [[ -e "${ET_DEVICE_LORA}" ]]; then INTERFACE_RNODE_ENABLED="yes" + + # Determine max power settings + et-log "Connecting to device to determine max power..." + + INTERFACE_RNODE_TXPOWER=`rnodeconf -i ${ET_DEVICE_LORA} | awk -F': ' '/Max TX power/ {print $2}' | awk '{print $1}'` + if [[ $? -ne 0 ]]; then + INTERFACE_RNODE_TXPOWER=${INTERFACE_RNODE_TXPOWER_DEFAULT} + et-log "Can't determine max power. Using defaulting ${INTERFACE_RNODE_TXPOWER}." + fi + + et-log "Setting max power to ${INTERFACE_RNODE_TXPOWER} dBm." + sed -i "s|{{ET_RETICULUM_INTERFACE_RNODE_TXPOWER}}|${INTERFACE_RNODE_TXPOWER}|g" ${RETICULUM_CONF_FILE} + else INTERFACE_RNODE_ENABLED="no" fi + sed -i "s|{{ET_RETICULUM_INTERFACE_RNODE_ENABLED}}|${INTERFACE_RNODE_ENABLED}|g" ${RETICULUM_CONF_FILE} -# 2. Determine max power settings -et-log "Connecting to device to determine max power..." -INTERFACE_RNODE_TXPOWER=`rnodeconf -i ${ET_DEVICE_LORA} | awk -F': ' '/Max TX power/ {print $2}' | awk '{print $1}'` -if [[ $? -ne 0 ]]; then - INTERFACE_RNODE_TXPOWER=${INTERFACE_RNODE_TXPOWER_DEFAULT} - et-log "Can't determine max power. Using defaulting ${INTERFACE_RNODE_TXPOWER}." -fi - -et-log "Setting max power to ${INTERFACE_RNODE_TXPOWER} dBm." -sed -i "s|{{ET_RETICULUM_INTERFACE_RNODE_TXPOWER}}|${INTERFACE_RNODE_TXPOWER}|g" ${RETICULUM_CONF_FILE} - CMD="rnsd" et-log "Starting Reticulum: ${CMD}" From b90e8b161f1ea7674ec04cf1a25e14cecf570863 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 15 Jun 2026 08:41:56 -0700 Subject: [PATCH 36/64] reticulum - Enabled AutoInterface on transport blueprint --- .../.reticulum/config.blueprint.permanent-transport-node | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node b/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node index b53df33..f670000 100644 --- a/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node +++ b/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node @@ -1,9 +1,10 @@ # Author : Gaston Gonzalez # Date : 7 June 2026 -# Updated : 14 June 2026 +# Updated : 15 June 2026 # Blueprint : Permament Transport Node -# Purpose : This configuration is a blueprint for running a node that -# as 24x7 transport node with multiple interfaces. +# Purpose : This configuration is a blueprint for running a +# node that runs as a 24x7 transport node with +# multiple interfaces. [reticulum] @@ -82,7 +83,7 @@ [[Default Interface]] type = AutoInterface - enabled = {{ET_RETICULUM_INTERFACE_AUTO_ENABLED}} + enabled = Yes [[Packet Radio AX.25 KISS]] type = AX25KISSInterface From 1efca3da441e575b90c567b9105920ffbb2e4b59 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 15 Jun 2026 08:53:15 -0700 Subject: [PATCH 37/64] reticulum - Add sample TCP Client intrface for those interested in enabling it manually --- .../config.blueprint.permanent-transport-node | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node b/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node index f670000..e173312 100644 --- a/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node +++ b/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node @@ -137,3 +137,18 @@ # fastest, and 8 the longest range. codingrate = 5 #codingrate = {{ET_RETICULUM_INTERFACE_RNODE_CODINGRATE}} + + # EmComm Tools is designed to be an offline platform, so the + # TCP Client interface is left as an example that user must + # configure. +# [[TCP Client]] +# type = TCPClientInterface +# enabled = Yes +# mode = boundary +# # Set the IP address to the remote TCP Server +# target_host = IP_ADDRESS_HERE +# target_port = 4242 +# # If the remote TCP Server uses IFAC (Interface Access Codes), +# # set the network_name and passphrase. +# #network_name = NETWORK_NAME_HERE +# #passphrase = PASSPHRASE_HERE From 21d51f780f90cce96a4ecf125112bcc7b3e7fb6c Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 15 Jun 2026 10:01:20 -0700 Subject: [PATCH 38/64] reticulum - Changed approach for running MeshChat. It's up to the user to ensure that rnsd is running --- overlay/opt/emcomm-tools/bin/et-meshchat-app | 44 ------------------- ...meshchat-1200.desktop => meshchat.desktop} | 6 +-- 2 files changed, 3 insertions(+), 47 deletions(-) delete mode 100755 overlay/opt/emcomm-tools/bin/et-meshchat-app rename overlay/usr/share/applications/{et-meshchat-1200.desktop => meshchat.desktop} (58%) diff --git a/overlay/opt/emcomm-tools/bin/et-meshchat-app b/overlay/opt/emcomm-tools/bin/et-meshchat-app deleted file mode 100755 index 2d369df..0000000 --- a/overlay/opt/emcomm-tools/bin/et-meshchat-app +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash -# -# Author : Gaston Gonzalez -# Date : 15 May 2026 -# Purpose : Wrapper script for starting MeshChat with PnP support -# -# Preconditions -# 1. Supported radio and audio interface are connected and properly detected -# -# Postconditions -# 1. Stop all running EmComm Tools modes -# 2. Start Dire Wolf in appropriate mode -# 3. Start Reticulum (rnsd) in appropriate mode -. /opt/emcomm-tools/bin/et-common - -usage() { - echo "usage: $(basename $0) " - echo " " - echo " 1200 - Run MeshChat with AX.25 interface over VHF/UHF (1200 baud)" - echo " 300 - Run MeshChat with AX.25 interface over HF (300 baud)" -} - -if [ $# -ne 1 ]; then - usage - exit 1 -fi - -et-kill-all - -MODE=$1 -case "${MODE}" in - "1200") - start_and_wait_for_service et-service-reticulum-1200 - ;; - "300") - start_and_wait_for_service et-service-reticulum-300 - ;; - *) - et-log "Unsupported mode." - exit 1 - ;; -esac - -et-meshchat diff --git a/overlay/usr/share/applications/et-meshchat-1200.desktop b/overlay/usr/share/applications/meshchat.desktop similarity index 58% rename from overlay/usr/share/applications/et-meshchat-1200.desktop rename to overlay/usr/share/applications/meshchat.desktop index a128eaf..8c7e8ea 100644 --- a/overlay/usr/share/applications/et-meshchat-1200.desktop +++ b/overlay/usr/share/applications/meshchat.desktop @@ -1,8 +1,8 @@ [Desktop Entry] Version=1.0 -Name=MeshChat 1200 -Comment=MeshChat over Reticulum using 1200 baud packet -Exec=/opt/emcomm-tools/bin/et-meshchat-app 1200 +Name=MeshChat +Comment=MeshChat +Exec=/opt/ReticulumMeshChat-2.3.0/bin/ReticulumMeshChat-v2.3.0-linux.AppImage Icon=/opt/ReticulumMeshChat-2.3.0/logo-chat-bubble.png Terminal=false X-MultipleArgs=false From 789953335bbf989eaf6ae5b081539f4461657a6f Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 15 Jun 2026 11:52:03 -0700 Subject: [PATCH 39/64] ETC R7 Build 5 Updates - Updated download link for pfte; upgrade Reticulum to 1.3.5; removed nomadnet temporarily from the installer due to dependency issues --- scripts/install-meshchat.sh | 4 ++-- scripts/install-pfte.sh | 3 ++- scripts/install-reticulum.sh | 16 +++++++--------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/scripts/install-meshchat.sh b/scripts/install-meshchat.sh index 58fc536..091d643 100755 --- a/scripts/install-meshchat.sh +++ b/scripts/install-meshchat.sh @@ -1,7 +1,7 @@ #!/bin/bash # Author : Gaston Gonzalez # Date : 13 May 2026 -# Updated : 15 May 2026 +# Updated : 15 June 2026 # Purpose : Install MeshChat for Reticulum set -e trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG @@ -47,4 +47,4 @@ ICON_URL="https://raw.githubusercontent.com/thetechprepper/reticulum-meshchat/ma download_with_retries ${ICON_URL} ${ICON} mv ${ICON} ${INSTALL_DIR} -cp ../overlay/usr/share/applications/et-meshchat-1200.desktop /usr/share/applications +cp ../overlay/usr/share/applications/meshchat.desktop /usr/share/applications diff --git a/scripts/install-pfte.sh b/scripts/install-pfte.sh index e26464f..348fb07 100755 --- a/scripts/install-pfte.sh +++ b/scripts/install-pfte.sh @@ -1,6 +1,7 @@ #!/bin/bash # Author : Gaston Gonzalez # Date : 27 March 2026 +# Updated : 15 June 2026 # Purpose : Install Paranoia File & Text Encryption set -e @@ -18,7 +19,7 @@ et-log "Installing ${APP} ${VERSION}..." if [[ ! -e ${ET_DIST_DIR}/${DOWNLOAD_FILE} ]]; then - URL="https://paranoiaworks.mobi/download/files/${DOWNLOAD_FILE}" + URL="https://paranoiaworks.com/download/pfte_15.0.8-1_amd64.deb" download_with_retries ${URL} ${DOWNLOAD_FILE} mv ${DOWNLOAD_FILE} ${ET_DIST_DIR} diff --git a/scripts/install-reticulum.sh b/scripts/install-reticulum.sh index 0724551..c0d234c 100755 --- a/scripts/install-reticulum.sh +++ b/scripts/install-reticulum.sh @@ -1,13 +1,12 @@ #!/bin/bash # Author : Gaston Gonzalez # Date : 13 February 2026 -# Updated : 11 May 2026 +# Updated : 15 June 2026 # Purpose : Install Reticulum -# Version pin Reticulum and Nomadnet as we want to favor stability +# Version pin Reticulum as we want to favor stability # above all other concerns (security, features, etc.). -RNS_VERSION=1.2.5 -NOMADNET_VERSION=0.9.8 +RNS_VERSION=1.3.5 et-log "Installing Python3..." apt install \ @@ -18,15 +17,14 @@ apt install \ et-log "Downloading rns ${RNS_VERSION} for offline install..." python3 -m pip download -d wheelhouse rns==${RNS_VERSION} -et-log "Downloading nomadnet ${NOMADNET_VERSION} for offline install..." -python3 -m pip download -d wheelhouse nomadnet==${NOMADNET_VERSION} +#et-log "Downloading nomadnet for offline install..." +#python3 -m pip download -d wheelhouse -et-log "Installing Reticulum and Nomadnet for single user use..." +et-log "Installing Reticulum for single user use..." PYTHONUSERBASE=/etc/skel/.local \ python3 -m pip install --user \ --no-index --find-links=wheelhouse \ - rns==${RNS_VERSION} \ - nomadnet==${NOMADNET_VERSION} + rns==${RNS_VERSION} et-log "Removing wheelhouse to save space..." [[ -e wheelhouse ]] && rm -vrf wheelhouse From 74d688e34bbe9cca8dd6ae466eaef34e36e2c9fb Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 15 Jun 2026 12:57:13 -0700 Subject: [PATCH 40/64] reticulum - Sorted list of blueprint configs --- overlay/opt/emcomm-tools/bin/et-reticulum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum index f2928fc..6f14cae 100755 --- a/overlay/opt/emcomm-tools/bin/et-reticulum +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -29,7 +29,7 @@ while IFS= read -r file; do files[$index]="$name" options+=("$index" "$name") ((index++)) -done < <(find "${HOME}/.reticulum" -type f -name 'config.blueprint.*') +done < <(find "${HOME}/.reticulum" -type f -name 'config.blueprint.*' | sort) choice=$(dialog \ --title "Reticulum Configuration" \ From a1f24f3524ee94d8158932eeaa984dc79f457525 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 15 Jun 2026 13:12:15 -0700 Subject: [PATCH 41/64] reticulum - Updates following ETC R7 Build 5 Reticulum testing. rnsd 1.3.5 does not work with NomadNet. Rolled back to version 1.2.5 --- scripts/install-reticulum.sh | 4 +++- tests/test-nomadnet.sh | 7 ------- 2 files changed, 3 insertions(+), 8 deletions(-) delete mode 100755 tests/test-nomadnet.sh diff --git a/scripts/install-reticulum.sh b/scripts/install-reticulum.sh index c0d234c..41ea753 100755 --- a/scripts/install-reticulum.sh +++ b/scripts/install-reticulum.sh @@ -6,7 +6,9 @@ # Version pin Reticulum as we want to favor stability # above all other concerns (security, features, etc.). -RNS_VERSION=1.3.5 +RNS_VERSION=1.2.5 +# WARNING: 1.3.5 does not work with MeshChat +#RNS_VERSION=1.3.5 et-log "Installing Python3..." apt install \ diff --git a/tests/test-nomadnet.sh b/tests/test-nomadnet.sh deleted file mode 100755 index 68daf78..0000000 --- a/tests/test-nomadnet.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -# Author : Gaston Gonzalez -# Date : 11 April 2025 -# Purpose : Test NomadNet installation - -OUT=$(PYTHONUSERBASE=/etc/skel/.local /etc/skel/.local/bin/nomadnet --version) -exit $? From eb8b7a0b50d116e9e0783c8c39ce46da0bad86d0 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 15 Jun 2026 13:26:09 -0700 Subject: [PATCH 42/64] reticulum - Added a sample comment for using an RNode over a TCP port --- .../skel/.reticulum/config.blueprint.permanent-transport-node | 1 + 1 file changed, 1 insertion(+) diff --git a/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node b/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node index e173312..206b869 100644 --- a/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node +++ b/overlay/etc/skel/.reticulum/config.blueprint.permanent-transport-node @@ -102,6 +102,7 @@ enabled = {{ET_RETICULUM_INTERFACE_RNODE_ENABLED}} port = /dev/et-lora + #port = tcp://192.168.8.200 # Set frequency to 915 MHz frequency = 915000000 From 7994eb3c42b6bc26357f7e00512fc62e48b628c2 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Thu, 18 Jun 2026 12:05:23 -0700 Subject: [PATCH 43/64] reticulum - Added a TCP client example to the TTP test network --- ...config.blueprint.internet-client-only-node | 125 ++++++++++++++++++ ... config.blueprint.local-network-only-node} | 0 2 files changed, 125 insertions(+) create mode 100644 overlay/etc/skel/.reticulum/config.blueprint.internet-client-only-node rename overlay/etc/skel/.reticulum/{config.blueprint.local-network-only => config.blueprint.local-network-only-node} (100%) diff --git a/overlay/etc/skel/.reticulum/config.blueprint.internet-client-only-node b/overlay/etc/skel/.reticulum/config.blueprint.internet-client-only-node new file mode 100644 index 0000000..40cc846 --- /dev/null +++ b/overlay/etc/skel/.reticulum/config.blueprint.internet-client-only-node @@ -0,0 +1,125 @@ +# Author : Gaston Gonzalez +# Date : 18 June 2026 +# Blueprint : Internet client only +# Purpose : This configuration is a blueprint for running a node that +# connects to a gateway node over the Internet using the +# TCPClientInterface. + +[reticulum] + + # If you enable Transport, your system will route traffic + # for other peers, pass announces and serve path requests. + # This should only be done for systems that are suited to + # act as transport nodes, ie. if they are stationary and + # always-on. This directive is optional and can be removed + # for brevity. + + enable_transport = False + + + # By default, the first program to launch the Reticulum + # Network Stack will create a shared instance, that other + # programs can communicate with. Only the shared instance + # opens all the configured interfaces directly, and other + # local programs communicate with the shared instance over + # a local socket. This is completely transparent to the + # user, and should generally be turned on. This directive + # is optional and can be removed for brevity. + + share_instance = Yes + + + # If you want to run multiple *different* shared instances + # on the same system, you will need to specify different + # instance names for each. On platforms supporting domain + # sockets, this can be done with the instance_name option: + + instance_name = default + + +# Some platforms don't support domain sockets, and if that +# is the case, you can isolate different instances by +# specifying a unique set of ports for each: + +# shared_instance_port = 37428 +# instance_control_port = 37429 + + +# If you want to explicitly use TCP for shared instance +# communication, instead of domain sockets, this is also +# possible, by using the following option: + +# shared_instance_type = tcp + + +# You can configure whether Reticulum should discover +# available interfaces from other Transport Instances over +# the network. If this option is enabled, Reticulum will +# collect interface information discovered from the network. + +# discover_interfaces = No + + +# You can configure Reticulum to panic and forcibly close +# if an unrecoverable interface error occurs, such as the +# hardware device for an interface disappearing. This is +# an optional directive, and can be left out for brevity. +# This behaviour is disabled by default. + +# panic_on_interface_error = No + + +# If you're connecting to a large external network, you +# can use one or more external blackhole list to block +# spammy and excessive announces onto your network. This +# funtionality is especially useful if you're hosting public +# entrypoints or gateways. The list source below provides a +# functional example, but better, more timely maintained +# lists probably exist in the community. + +# blackhole_sources = 521c87a83afb8f29e4455e77930b973b + + +[logging] + # Valid log levels are 0 through 7: + # 0: Log only critical information + # 1: Log errors and lower log levels + # 2: Log warnings and lower log levels + # 3: Log notices and lower log levels + # 4: Log info and lower (this is the default) + # 5: Verbose logging + # 6: Debug logging + # 7: Extreme logging + + loglevel = 4 + + +# The interfaces section defines the physical and virtual +# interfaces Reticulum will use to communicate on. This +# section will contain examples for a variety of interface +# types. You can modify these or use them as a basis for +# your own config, or simply remove the unused ones. + +[interfaces] + + # This interface enables communication with other + # link-local Reticulum nodes over UDP. It does not + # need any functional IP infrastructure like routers + # or DHCP servers, but will require that at least link- + # local IPv6 is enabled in your operating system, which + # should be enabled by default in almost any OS. See + # the Reticulum Manual for more configuration options. + + [[Default Interface]] + type = AutoInterface + enabled = no + + [[TCP Client to TTP Gateway]] + type = TCPClientInterface + mode = boundary + enabled = yes + target_host = rns.thetechprepper.com + target_port = 11312 + network_name = ttp_internal + passphrase = resistance202606 + diff --git a/overlay/etc/skel/.reticulum/config.blueprint.local-network-only b/overlay/etc/skel/.reticulum/config.blueprint.local-network-only-node similarity index 100% rename from overlay/etc/skel/.reticulum/config.blueprint.local-network-only rename to overlay/etc/skel/.reticulum/config.blueprint.local-network-only-node From 3f6017666838568eeea9192407f5e23d6e1fdbb1 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 23 Jun 2026 10:52:43 -0700 Subject: [PATCH 44/64] reticulum - Upgraded Reticulum to version 1.3.5 --- scripts/install-reticulum.sh | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/scripts/install-reticulum.sh b/scripts/install-reticulum.sh index 41ea753..a3b3f8f 100755 --- a/scripts/install-reticulum.sh +++ b/scripts/install-reticulum.sh @@ -1,14 +1,10 @@ #!/bin/bash # Author : Gaston Gonzalez # Date : 13 February 2026 -# Updated : 15 June 2026 +# Updated : 23 June 2026 # Purpose : Install Reticulum -# Version pin Reticulum as we want to favor stability -# above all other concerns (security, features, etc.). -RNS_VERSION=1.2.5 -# WARNING: 1.3.5 does not work with MeshChat -#RNS_VERSION=1.3.5 +RNS_VERSION=1.3.5 et-log "Installing Python3..." apt install \ @@ -28,5 +24,5 @@ PYTHONUSERBASE=/etc/skel/.local \ --no-index --find-links=wheelhouse \ rns==${RNS_VERSION} -et-log "Removing wheelhouse to save space..." -[[ -e wheelhouse ]] && rm -vrf wheelhouse +#et-log "Removing wheelhouse to save space..." +#[[ -e wheelhouse ]] && rm -vrf wheelhouse From 18a917e9f6f13ea49f873ee656c2df05aa820076 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 23 Jun 2026 11:02:49 -0700 Subject: [PATCH 45/64] reticulum - Added a modified version of MeshChat --- overlay/usr/share/applications/meshchat.desktop | 4 ++-- scripts/install-meshchat.sh | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/overlay/usr/share/applications/meshchat.desktop b/overlay/usr/share/applications/meshchat.desktop index 8c7e8ea..c0f6e9b 100644 --- a/overlay/usr/share/applications/meshchat.desktop +++ b/overlay/usr/share/applications/meshchat.desktop @@ -2,8 +2,8 @@ Version=1.0 Name=MeshChat Comment=MeshChat -Exec=/opt/ReticulumMeshChat-2.3.0/bin/ReticulumMeshChat-v2.3.0-linux.AppImage -Icon=/opt/ReticulumMeshChat-2.3.0/logo-chat-bubble.png +Exec=/opt/emcomm-tools/bin/et-meshchat +Icon=/opt/ReticulumMeshChat/logo-chat-bubble.png Terminal=false X-MultipleArgs=false Type=Application diff --git a/scripts/install-meshchat.sh b/scripts/install-meshchat.sh index 091d643..39d078c 100755 --- a/scripts/install-meshchat.sh +++ b/scripts/install-meshchat.sh @@ -1,7 +1,7 @@ #!/bin/bash # Author : Gaston Gonzalez # Date : 13 May 2026 -# Updated : 15 June 2026 +# Updated : 23 June 2026 # Purpose : Install MeshChat for Reticulum set -e trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG @@ -11,13 +11,13 @@ trap 'et-log "\"${last_command}\" command failed with exit code $?."' ERR . ../overlay/opt/emcomm-tools/bin/et-common APP=ReticulumMeshChat -VERSION=2.3.0 +VERSION="2.3.0-R7B7" INSTALL_DIR="/opt/${APP}-${VERSION}" INSTALL_BIN_DIR="${INSTALL_DIR}/bin" LINK_PATH="/opt/${APP}" DOWNLOAD_FILE="${APP}-v${VERSION}-linux.AppImage" -URL="https://github.com/liamcottle/reticulum-meshchat/releases/download/v${VERSION}/${DOWNLOAD_FILE}" +URL="https://github.com/thetechprepper/reticulum-meshchat/releases/download/${VERSION}/ReticulumMeshChat-v${VERSION}-linux.AppImage" et-log "Installing ${APP} ${VERSION}..." @@ -48,3 +48,8 @@ download_with_retries ${ICON_URL} ${ICON} mv ${ICON} ${INSTALL_DIR} cp ../overlay/usr/share/applications/meshchat.desktop /usr/share/applications + +[[ -e ${LINK_PATH} ]] && rm ${LINK_PATH} +ln -s ${INSTALL_DIR} ${LINK_PATH} + +stow -v -d /opt ${APP} -t /usr/local From 252c9b8fbc287d03dd674296c255693fc4d44531 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 28 Jun 2026 11:03:20 -0700 Subject: [PATCH 46/64] Initial support for modem73 --- scripts/install-modem73.sh | 44 ++++++++++++++++++++++++++++++++++++++ scripts/install.sh | 5 +++-- tests/test-modem73.sh | 7 ++++++ 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100755 scripts/install-modem73.sh create mode 100755 tests/test-modem73.sh diff --git a/scripts/install-modem73.sh b/scripts/install-modem73.sh new file mode 100755 index 0000000..b04d1dc --- /dev/null +++ b/scripts/install-modem73.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# Author : Gaston Gonzalez +# Date : 28 June 2026 +# Purpose : Installs modem73 +set -e +trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG +trap 'et-log "\"${last_command}\" command failed with exit code $?."' ERR + +. ./env.sh + +APP="modem73" +VERSION="1.0.7" +APP_AND_VERSION="${APP}-${VERSION}" +GIT_URL="https://github.com/thetechprepper/modem73.git" +GIT_WORKSPACE="modem73" +INSTALL_DIR="/opt/${APP_AND_VERSION}" +INSTALL_BIN_DIR="${INSTALL_DIR}/bin" +LINK_PATH="/opt/${APP}" + +et-log "Installing ${APP} dependencies..." +apt install \ + libncurses-dev \ + -y + +et-log "Installing ${APP} ${VERSION}" + +CWD_DIR=`pwd` + +cd ${ET_SRC_DIR} +[[ ! -e ${GIT_WORKSPACE} ]] && git clone ${GIT_URL} ${GIT_WORKSPACE} + +cd ${GIT_WORKSPACE} +make + +[[ ! -e "${INSTALL_BIN_DIR}" ]] && mkdir -v -p "${INSTALL_BIN_DIR}" +[[ -e "${APP}" ]] && cp ${APP} "${INSTALL_BIN_DIR}" + + +[[ -e ${LINK_PATH} ]] && rm ${LINK_PATH} +ln -v -s ${INSTALL_DIR} ${LINK_PATH} + +stow -v -d /opt ${APP} -t /usr/local + +cd ${CWD} diff --git a/scripts/install.sh b/scripts/install.sh index 2e283d6..81aee52 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 16 March 2024 -# Updated : 13 May 2026 +# Updated : 28 June 2026 # Purpose : Main installer for EmComm Tools Community (ETC) . ./env.sh @@ -119,9 +119,10 @@ exitIfNotRoot # Security Patches ./patch-copy-fail.sh -# Install Reticulum and related applications (NomadNet, MeshChat) +# Install Reticulum and related applications ./install-reticulum.sh ./install-meshchat.sh +./install-modem73.sh # Debrand Ubuntu ./debrand.sh diff --git a/tests/test-modem73.sh b/tests/test-modem73.sh new file mode 100755 index 0000000..753791e --- /dev/null +++ b/tests/test-modem73.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# Author : Gaston Gonzalez +# Date : 28 June 2026 +# Purpose : Test modem73 installation + +OUT=$(which modem73) +exit $? From d572bdff34b8f89e8d4b29cae8265d93d8243efb Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 28 Jun 2026 11:10:44 -0700 Subject: [PATCH 47/64] modem73 - Add modem73 user systemd service --- .../user/et-service-modem73-default.service | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 overlay/etc/skel/.config/systemd/user/et-service-modem73-default.service diff --git a/overlay/etc/skel/.config/systemd/user/et-service-modem73-default.service b/overlay/etc/skel/.config/systemd/user/et-service-modem73-default.service new file mode 100644 index 0000000..8e7e4a6 --- /dev/null +++ b/overlay/etc/skel/.config/systemd/user/et-service-modem73-default.service @@ -0,0 +1,20 @@ +# Author : Gaston Gonzalez +# Date : 28 June 2026 +# Purpose : User systemd unit file for EmComm Tools that starts modem73 +# : in a default configuration. +# +# Usage: +# Check status : systemctl --user status et-service-modem73-default +# Start service : systemctl --user start et-service-modem73-default +# Stop service : systemctl --user stop et-service-modem73-default +# Reload this config : systemctl --user daemon-reload + +[Unit] +Description=EmComm Tools modem73 default service + +[Service] +ExecStart=/opt/emcomm-tools/bin/et-modem73 start default +Restart=no + +[Install] +WantedBy=multi-user.target From 2fffb147c80dd5d1aea1077c4906e5393b8a81fe Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 28 Jun 2026 12:29:06 -0700 Subject: [PATCH 48/64] modem73 - Patched my fork of modem73 to use the ALSA backend in order to support audio PnP in EmComm Tools --- scripts/install-modem73.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/install-modem73.sh b/scripts/install-modem73.sh index b04d1dc..81dc1d0 100755 --- a/scripts/install-modem73.sh +++ b/scripts/install-modem73.sh @@ -27,7 +27,7 @@ et-log "Installing ${APP} ${VERSION}" CWD_DIR=`pwd` cd ${ET_SRC_DIR} -[[ ! -e ${GIT_WORKSPACE} ]] && git clone ${GIT_URL} ${GIT_WORKSPACE} +[[ ! -e ${GIT_WORKSPACE} ]] && git clone --branch emcomm-tools --single-branch ${GIT_URL} cd ${GIT_WORKSPACE} make From d3a12fd664e585b68ee2daa93697d05e006f6157 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 28 Jun 2026 12:48:05 -0700 Subject: [PATCH 49/64] modem73 - Initial PnP wrapper script for modem73 --- overlay/opt/emcomm-tools/bin/et-modem73 | 121 ++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100755 overlay/opt/emcomm-tools/bin/et-modem73 diff --git a/overlay/opt/emcomm-tools/bin/et-modem73 b/overlay/opt/emcomm-tools/bin/et-modem73 new file mode 100755 index 0000000..a807094 --- /dev/null +++ b/overlay/opt/emcomm-tools/bin/et-modem73 @@ -0,0 +1,121 @@ +#!/bin/bash +# +# Author : Gaston Gonzalez +# Date : 28 June 2026 +# Purpose : Wrapper script for starting modem73 with PnP support +# +# Preconditions: +# 1. Supported radio and audio interface are connected and properly detected +# +# Postconditions: +# 1. modem73 started with sane defaults + +MODEM73_CONF_FILE=${ET_HOME}/conf/template.d/modem73/settings.default + +usage() { + echo "usage: $(basename $0) " + echo " " + echo " start - Start modem73 in selected mode" + echo " update-config - Update configuration for selected mode" + echo "" + echo " " + echo " default - QPSK, normal frames, 1/2 code rate (recommended)" +} + +if [[ $# -ne 2 ]]; then + usage + exit 1 +fi + +MODE=$2 +case "${MODE}" in + default) + et-log "Configuration updates not yet implemented." + ;; + *) + et-log "Can't started modem73. Mode '${MODE}' not supported" + usage + exit 1 + ;; +esac + +notify_user() { + notify-send \ + -t 10000 \ + --app-name="EmComm Tools" \ + "$1" +} + +[ -z ${ET_LOG_DIR} ] && ET_LOG_DIR="${HOME}/.local/share/emcomm-tools" +[ ! -e ${ET_LOG_DIR} ] && mkdir -p ${ET_LOG_DIR} + +start() { + update_config + + if [ $? -eq 0 ]; then + + systemctl is-active --quiet rigctld + if [ $? -ne 0 ]; then + et-log "Can't start modem73. rigctld not running. Ensure radio is selected." + notify_user "Can't start modem73. rigctld not running." + exit 1 + fi + + ALSA_DEVICE=$(et-system-info et-audio-card) + INPUT_AUDIO=$(modem73 --list-audio | grep input | grep $ALSA_DEVICE | cut -d":" -f3) + OUTPUT_AUDIO=$(modem73 --list-audio | grep output| grep $ALSA_DEVICE | cut -d":" -f3) + + CMD="modem73 --input-device ${INPUT_AUDIO} --output-device ${OUTPUT_AUDIO} --ptt rigctl --headless" + et-log "Starting modem73 with: '${CMD}'" + echo + ${CMD} + else + et-log "Error updating configuration. Can't start modem73" + exit 1 + fi +} + +update_config () { + + et-log "Attempting to start modem73 in mode: '${MODE}'" + + [ -z "$ET_USER_CONFIG" ] && ET_USER_CONFIG="${HOME}/.config/emcomm-tools/user.json" + + CALLSIGN=$(cat ${ET_USER_CONFIG} | jq -r .callsign) + + # 1. Check if the symlink was created by the udev rules + if [ -e /dev/et-audio ]; then + + # 2. Check that this device was properly tagged with the ET_AUDIO env variable with a udev rule + APLAY_OUT=$(arecord -l | grep ET_AUDIO) + if [ $? -eq 0 ]; then + + # Configure ALSA settings for sound card + /opt/emcomm-tools/bin/et-audio update-config + + else + et-log "No ET_AUDIO device detected." + notify_user "Can't start modem73. No ET_AUDIO device detected." + exit 1 + fi + else + et-log "No ET_AUDIO device plugged in." + notify_user "Can't start modem73. No supported audio device plugged in." + exit 1 + fi + +} + +case $1 in + start) + start + ;; + update-config) + update_config + ;; + *) + echo "Invalid command." + usage + exit 1 + ;; +esac From f3f9f8585304613c6afe0619b9039c28ae331892 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 28 Jun 2026 13:00:23 -0700 Subject: [PATCH 50/64] modem73 - Add support for stopping all services to support a clean start of Reticulum --- overlay/opt/emcomm-tools/bin/et-kill-all | 3 ++- overlay/opt/emcomm-tools/bin/et-reticulum | 18 +++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-kill-all b/overlay/opt/emcomm-tools/bin/et-kill-all index 62839f9..151d1ce 100755 --- a/overlay/opt/emcomm-tools/bin/et-kill-all +++ b/overlay/opt/emcomm-tools/bin/et-kill-all @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 12 November 2024 -# Updated : 12 May 2026 +# Updated : 28 June 2026 # Purpose : Stops all EmComm Tools sound-based services (i.e. modems) and # amatuer radio applications to ensure a clean start for the next mode. @@ -29,6 +29,7 @@ stop_all_services() { systemctl --user stop et-service-direwolf-simple systemctl --user stop et-service-direwolf-aprs-digipeater systemctl --user stop et-service-direwolf-packet-digipeater + systemctl --user stop et-service-modem73-default # Stop VARA with a sledge hammer pkill et-winlink diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum index 6f14cae..299abad 100755 --- a/overlay/opt/emcomm-tools/bin/et-reticulum +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 12 May 2026 -# Updated : 15 May 2026 +# Updated : 28 June 2026 # Purpose : Wrapper script for starting Reticulum with PnP support # # Preconditions: @@ -14,6 +14,9 @@ # 3. Reticulum started . /opt/emcomm-tools/bin/et-common +# Ensure that no other modes are running +et-kill-all + APP="Reticulum" RETICULUM_CONF_DIR="${HOME}/.reticulum" RETICULUM_CONF_FILE="${RETICULUM_CONF_DIR}/config" @@ -81,8 +84,9 @@ if [[ $? -eq 0 ]]; then et-log "Radio connected and detected." modem_options=() - modem_options+=("1200" "1200 baud (VHF/UHF operation)") - modem_options+=("300" "300 baud (HF option)") + modem_options+=("1200-packet" "1200 baud packet (VHF/UHF)") + modem_options+=("300-packet" "300 baud packet (HF)") + modem_options+=("modem73-default" "modem73 (HF/VHF/UHF)") modem_choice=$(dialog \ --clear \ @@ -104,14 +108,18 @@ if [[ $? -eq 0 ]]; then et-log "User canceled modem selection. Packet modem will not be started and interface will not be enabled." else case ${modem_choice} in - 300) + 300-packet) et-log "Starting 300 baud packet modem" start_and_wait_for_service et-service-direwolf-300 ;; - 1200) + 1200-packet) et-log "Starting 1200 baud packet modem" start_and_wait_for_service et-service-direwolf-simple ;; + modem73-default) + et-log "Starting modem73 with defaults" + start_and_wait_for_service et-service-modem73-default + ;; *) et-log "No modem specified" ;; From 5af3630ca7cde49cbe0b956541696c627ee0cbe0 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 28 Jun 2026 13:06:49 -0700 Subject: [PATCH 51/64] modem73 - Added a blueprint for a modem73 interface --- .../.reticulum/config.blueprint.modem73-node | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 overlay/etc/skel/.reticulum/config.blueprint.modem73-node diff --git a/overlay/etc/skel/.reticulum/config.blueprint.modem73-node b/overlay/etc/skel/.reticulum/config.blueprint.modem73-node new file mode 100644 index 0000000..a86acf1 --- /dev/null +++ b/overlay/etc/skel/.reticulum/config.blueprint.modem73-node @@ -0,0 +1,136 @@ +# Author : Gaston Gonzalez +# Date : 28 June 2026 +# Blueprint : Radio-Only Node, transport disabled +# Purpose : This confguration is a blueprint for a radio-only node +# that modem73 as the radio interface. If a supported +# et-lora device is detected, it will be enabled, too. + +[reticulum] + + # If you enable Transport, your system will route traffic + # for other peers, pass announces and serve path requests. + # This should only be done for systems that are suited to + # act as transport nodes, ie. if they are stationary and + # always-on. This directive is optional and can be removed + # for brevity. + + enable_transport = False + + + # By default, the first program to launch the Reticulum + # Network Stack will create a shared instance, that other + # programs can communicate with. Only the shared instance + # opens all the configured interfaces directly, and other + # local programs communicate with the shared instance over + # a local socket. This is completely transparent to the + # user, and should generally be turned on. This directive + # is optional and can be removed for brevity. + + share_instance = Yes + + + # If you want to run multiple *different* shared instances + # on the same system, you will need to specify different + # instance names for each. On platforms supporting domain + # sockets, this can be done with the instance_name option: + + instance_name = default + +# You can configure whether Reticulum should discover +# available interfaces from other Transport Instances over +# the network. If this option is enabled, Reticulum will +# collect interface information discovered from the network. + +# discover_interfaces = No + + +# You can configure Reticulum to panic and forcibly close +# if an unrecoverable interface error occurs, such as the +# hardware device for an interface disappearing. This is +# an optional directive, and can be left out for brevity. +# This behaviour is disabled by default. + +# panic_on_interface_error = No + + +# If you're connecting to a large external network, you +# can use one or more external blackhole list to block +# spammy and excessive announces onto your network. This +# funtionality is especially useful if you're hosting public +# entrypoints or gateways. The list source below provides a +# functional example, but better, more timely maintained +# lists probably exist in the community. + +# blackhole_sources = 521c87a83afb8f29e4455e77930b973b + + +[logging] + # Valid log levels are 0 through 7: + # 0: Log only critical information + # 1: Log errors and lower log levels + # 2: Log warnings and lower log levels + # 3: Log notices and lower log levels + # 4: Log info and lower (this is the default) + # 5: Verbose logging + # 6: Debug logging + # 7: Extreme logging + + loglevel = 4 + + +[interfaces] + + [[Default Interface]] + type = AutoInterface + enabled = No + + [[RNode LoRa Interface]] + type = RNodeInterface + mode = roaming + enabled = {{ET_RETICULUM_INTERFACE_RNODE_ENABLED}} + + port = /dev/et-lora + + # Set frequency to 915 MHz + frequency = 915000000 + #frequency = {{ET_RETICULUM_INTERFACE_RNODE_FREQUENCY}} + + # Set LoRa bandwidth to 125 KHz + bandwidth = 125000 + #bandwidth = {{ET_RETICULUM_INTERFACE_RNODE_BANDWIDTH}} + + # Set TX power in dBm + # + # 7 dBm = 5 mW + # 10 dBm = 10 mW + # 14 dBm = 25 mW + # 17 dBm = 50 mW + # 20 dBm = 100 mW + # 22 dBm = 158 mW + # 24 dBm = 251 mW + # 27 dBm = 501 mW + # 28 dBm = 631 mW + # 30 dBm = 1000 mW (1 W) + txpower = {{ET_RETICULUM_INTERFACE_RNODE_TXPOWER}} + + # Select spreading factor 8. Valid + # range is 7 through 12, with 7 + # being the fastest and 12 having + # the longest range. + spreadingfactor = 9 + #spreadingfactor = {{ET_RETICULUM_INTERFACE_RNODE_SPREADINGFACTOR}} + + # Select coding rate 5. Valid range + # is 5 throough 8, with 5 being the + # fastest, and 8 the longest range. + codingrate = 5 + #codingrate = {{ET_RETICULUM_INTERFACE_RNODE_CODINGRATE}} + + [[modem73]] + type = Modem73Interface + enabled = yes + target_host = 127.0.0.1 + target_port = 8001 + control_host = 127.0.0.1 + control_port = 8073 + From a2e55f3b57f7608f65ee53b77781fe6afe494b6b Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 28 Jun 2026 13:16:34 -0700 Subject: [PATCH 52/64] modem73 - Added modem73 interface to Reticulum installation --- scripts/install-modem73.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/scripts/install-modem73.sh b/scripts/install-modem73.sh index 81dc1d0..46df0bf 100755 --- a/scripts/install-modem73.sh +++ b/scripts/install-modem73.sh @@ -7,6 +7,7 @@ trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG trap 'et-log "\"${last_command}\" command failed with exit code $?."' ERR . ./env.sh +. ../overlay/opt/emcomm-tools/bin/et-common APP="modem73" VERSION="1.0.7" @@ -42,3 +43,15 @@ ln -v -s ${INSTALL_DIR} ${LINK_PATH} stow -v -d /opt ${APP} -t /usr/local cd ${CWD} + + +et-log "Enabling modem73 interface..." + +INTERFACE_FILE=Modem73Interface.py +INTERFACE_DIR=/etc/skel/.reticulum/interfaces + +download_with_retries https://raw.githubusercontent.com/thetechprepper/modem73interface/refs/heads/master/Modem73Interface.py ${INTERFACE_FILE} + +[[ ! -e ${INTERFACE_DIR} ]] && mkdir -v -p ${INTERFACE_DIR} +mv -v ${INTERFACE_FILE} /etc/skel/.reticulum/interfaces + From 257037b273ffc7670af534d2349ab29597578e9e Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 28 Jun 2026 16:22:28 -0700 Subject: [PATCH 53/64] reticulum - Updated et-reticulum to restrict the list of radio modem options based on the interfaces defined in the blueprint. --- overlay/opt/emcomm-tools/bin/et-reticulum | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum index 299abad..99301fd 100755 --- a/overlay/opt/emcomm-tools/bin/et-reticulum +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -84,9 +84,17 @@ if [[ $? -eq 0 ]]; then et-log "Radio connected and detected." modem_options=() - modem_options+=("1200-packet" "1200 baud packet (VHF/UHF)") - modem_options+=("300-packet" "300 baud packet (HF)") - modem_options+=("modem73-default" "modem73 (HF/VHF/UHF)") + + HAS_PACKET_CONFIG=`grep AX25KISSInterface ~/.reticulum/config` + if [[ $? -eq 0 ]]; then + modem_options+=("1200-packet" "1200 baud packet (VHF/UHF)") + modem_options+=("300-packet" "300 baud packet (HF)") + fi + + HAS_MODEM73_CONFIG=`grep Modem73Interface ~/.reticulum/config` + if [[ $? -eq 0 ]]; then + modem_options+=("modem73-default" "modem73 (HF/VHF/UHF)") + fi modem_choice=$(dialog \ --clear \ From f5fb54c88526b95199bb4ead212b1af0f953309f Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 28 Jun 2026 16:29:19 -0700 Subject: [PATCH 54/64] reticulum - Renamed the radio only interface to packet now that we have modem73 as anothor radio options --- overlay/etc/skel/.reticulum/config.blueprint.modem73-node | 5 +++-- ...t.radio-only-node => config.blueprint.packet-only-node} | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) rename overlay/etc/skel/.reticulum/{config.blueprint.radio-only-node => config.blueprint.packet-only-node} (96%) diff --git a/overlay/etc/skel/.reticulum/config.blueprint.modem73-node b/overlay/etc/skel/.reticulum/config.blueprint.modem73-node index a86acf1..3fa2ba1 100644 --- a/overlay/etc/skel/.reticulum/config.blueprint.modem73-node +++ b/overlay/etc/skel/.reticulum/config.blueprint.modem73-node @@ -1,8 +1,8 @@ # Author : Gaston Gonzalez # Date : 28 June 2026 # Blueprint : Radio-Only Node, transport disabled -# Purpose : This confguration is a blueprint for a radio-only node -# that modem73 as the radio interface. If a supported +# Purpose : This confguration is a blueprint for a radio-only node. +# It uses modem73 as the radio interface. If a supported # et-lora device is detected, it will be enabled, too. [reticulum] @@ -128,6 +128,7 @@ [[modem73]] type = Modem73Interface + mode = roaming enabled = yes target_host = 127.0.0.1 target_port = 8001 diff --git a/overlay/etc/skel/.reticulum/config.blueprint.radio-only-node b/overlay/etc/skel/.reticulum/config.blueprint.packet-only-node similarity index 96% rename from overlay/etc/skel/.reticulum/config.blueprint.radio-only-node rename to overlay/etc/skel/.reticulum/config.blueprint.packet-only-node index 3917653..6b47185 100644 --- a/overlay/etc/skel/.reticulum/config.blueprint.radio-only-node +++ b/overlay/etc/skel/.reticulum/config.blueprint.packet-only-node @@ -1,10 +1,11 @@ # Author : Gaston Gonzalez # Date : 7 June 2026 -# Updated : 15 June 2026 +# Updated : 28 June 2026 # Blueprint : Radio-Only Node, transport disabled # Purpose : This confguration is a blueprint for a radio-only node. -# If a supported et-radio and/or et-lora device is -# detected, they will be enabled. +# It uses an AX.25 KISS radio interface. If a supported +# et-lora device is detected, it will be enabled, too. + [reticulum] From 32179bd18d9634864f4dd6ce0cc8bfbf70539a2d Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Sun, 28 Jun 2026 16:46:46 -0700 Subject: [PATCH 55/64] retiuclum - Added support to dynamically enable/disable modem73 depending on the system state --- overlay/etc/skel/.reticulum/README.md | 1 + ...em73-node => config.blueprint.modem73-only-node} | 3 +-- overlay/opt/emcomm-tools/bin/et-reticulum | 13 +++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) rename overlay/etc/skel/.reticulum/{config.blueprint.modem73-node => config.blueprint.modem73-only-node} (98%) diff --git a/overlay/etc/skel/.reticulum/README.md b/overlay/etc/skel/.reticulum/README.md index 4e0955c..ede9738 100644 --- a/overlay/etc/skel/.reticulum/README.md +++ b/overlay/etc/skel/.reticulum/README.md @@ -26,6 +26,7 @@ the supported tokens below. ET_CALLSIGN ET_RETICULUM_INTERFACE_AUTO_ENABLED ET_RETICULUM_INTERFACE_AX25KISS_ENABLED +ET_RETICULUM_INTERFACE_MODEM73_ENABLED ET_RETICULUM_INTERFACE_RNODE_BANDWIDTH ET_RETICULUM_INTERFACE_RNODE_CODINGRATE ET_RETICULUM_INTERFACE_RNODE_ENABLED diff --git a/overlay/etc/skel/.reticulum/config.blueprint.modem73-node b/overlay/etc/skel/.reticulum/config.blueprint.modem73-only-node similarity index 98% rename from overlay/etc/skel/.reticulum/config.blueprint.modem73-node rename to overlay/etc/skel/.reticulum/config.blueprint.modem73-only-node index 3fa2ba1..e3b6e85 100644 --- a/overlay/etc/skel/.reticulum/config.blueprint.modem73-node +++ b/overlay/etc/skel/.reticulum/config.blueprint.modem73-only-node @@ -129,9 +129,8 @@ [[modem73]] type = Modem73Interface mode = roaming - enabled = yes + enabled = {{ET_RETICULUM_INTERFACE_MODEM73_ENABLED}} target_host = 127.0.0.1 target_port = 8001 control_host = 127.0.0.1 control_port = 8073 - diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum index 99301fd..4c53d18 100755 --- a/overlay/opt/emcomm-tools/bin/et-reticulum +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -137,6 +137,19 @@ fi et-log "Updating configuration for this session..." +############################################################ +# MODEM73 interface updates +############################################################ + +# Enable/disable intereface based on PnP device detection +IS_MODEM73_RUNNING=`ps -ef | grep [m]odem73` +if [[ $? -eq 0 ]]; then + INTERFACE_MODEM73_ENABLED="yes" +else + INTERFACE_MODEM73_ENABLED="no" +fi +sed -i "s|{{ET_RETICULUM_INTERFACE_MODEM73_ENABLED}}|${INTERFACE_MODEM73_ENABLED}|g" ${RETICULUM_CONF_FILE} + ############################################################ # AX.25 KISS (Packet Radio) interface updates ############################################################ From bbb0417c5054abfee51c01a016e33b7536a95160 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 29 Jun 2026 06:49:59 -0700 Subject: [PATCH 56/64] modem73 - Force stop modem73 if it will not exit --- overlay/opt/emcomm-tools/bin/et-kill-all | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-kill-all b/overlay/opt/emcomm-tools/bin/et-kill-all index 151d1ce..bea4a3e 100755 --- a/overlay/opt/emcomm-tools/bin/et-kill-all +++ b/overlay/opt/emcomm-tools/bin/et-kill-all @@ -2,9 +2,9 @@ # # Author : Gaston Gonzalez # Date : 12 November 2024 -# Updated : 28 June 2026 -# Purpose : Stops all EmComm Tools sound-based services (i.e. modems) and -# amatuer radio applications to ensure a clean start for the next mode. +# Updated : 29 June 2026 +# Purpose : Stops all EmComm Tools soundcard-based services (i.e. modems) +# and radio applications to ensure a clean start for the next mode. stop_pat() { PS_OUT=$(ps -ef | grep "[p]at http") @@ -21,15 +21,17 @@ stop_all_services() { systemctl --user stop et-service-winlink-ardop systemctl --user stop et-service-winlink-packet systemctl --user stop et-service-winlink-native-packet - systemctl --user stop et-service-reticulum-300 - systemctl --user stop et-service-reticulum-1200 systemctl --user stop et-service-ardop systemctl --user stop et-service-direwolf-300 systemctl --user stop et-service-direwolf-9600 systemctl --user stop et-service-direwolf-simple systemctl --user stop et-service-direwolf-aprs-digipeater systemctl --user stop et-service-direwolf-packet-digipeater + + # Stop modem73 with a sledge hammer (belt and suspenders) as the current + # 1.0.7 version can hang on exit. systemctl --user stop et-service-modem73-default + pkill -9 modem73 # Stop VARA with a sledge hammer pkill et-winlink From 5419c48b9bb231185e9bc6d1fb8298c50de632a8 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 30 Jun 2026 11:59:53 -0700 Subject: [PATCH 57/64] modem73 - Added support for force killing modem73 on application exit --- overlay/opt/emcomm-tools/bin/et-reticulum | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum index 4c53d18..576d60e 100755 --- a/overlay/opt/emcomm-tools/bin/et-reticulum +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 12 May 2026 -# Updated : 28 June 2026 +# Updated : 30 June 2026 # Purpose : Wrapper script for starting Reticulum with PnP support # # Preconditions: @@ -12,6 +12,14 @@ # 1. Reticulum configuration updated # 2. Optional modem started # 3. Reticulum started + +# The current version of modem73 does not alway exit. +cleanup() { + pkill -9 modem73 2>/dev/null || true +} + +trap cleanup EXIT INT TERM + . /opt/emcomm-tools/bin/et-common # Ensure that no other modes are running From 237f575611010bd53bcf264e4a9db3abdde2b30d Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 30 Jun 2026 12:24:34 -0700 Subject: [PATCH 58/64] modem73 - Removed settings file before each run to prevent inconsistent or incorrect configuration for ETC --- overlay/opt/emcomm-tools/bin/et-modem73 | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-modem73 b/overlay/opt/emcomm-tools/bin/et-modem73 index a807094..bb32d1c 100755 --- a/overlay/opt/emcomm-tools/bin/et-modem73 +++ b/overlay/opt/emcomm-tools/bin/et-modem73 @@ -1,7 +1,7 @@ #!/bin/bash # # Author : Gaston Gonzalez -# Date : 28 June 2026 +# Date : 30 June 2026 # Purpose : Wrapper script for starting modem73 with PnP support # # Preconditions: @@ -10,7 +10,7 @@ # Postconditions: # 1. modem73 started with sane defaults -MODEM73_CONF_FILE=${ET_HOME}/conf/template.d/modem73/settings.default +MODEM73_CONF_FILE="${HOME}/.config/modem73/settings" usage() { echo "usage: $(basename $0) " @@ -77,6 +77,14 @@ start() { update_config () { + # The modem73 configuration file causes issues when using it in combination with + # command line arguments during manual runs. It is best to remove it before each + # run and drive the modem using only command line arguments. + if [[ -e "${MODEM73_CONF_FILE}" ]]; then + et-log "Removing previous configuration file: ${MODEM73_CONF_FILE}" + rm -v ${MODEM73_CONF_FILE} + fi + et-log "Attempting to start modem73 in mode: '${MODE}'" [ -z "$ET_USER_CONFIG" ] && ET_USER_CONFIG="${HOME}/.config/emcomm-tools/user.json" From 3030d02ceacee661867b662a15deda9c0f5dcc31 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 30 Jun 2026 13:03:12 -0700 Subject: [PATCH 59/64] modem73 - Changed the command line interface to support only the mode and optional --headless argument --- overlay/opt/emcomm-tools/bin/et-modem73 | 83 ++++++++++++------------- 1 file changed, 39 insertions(+), 44 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-modem73 b/overlay/opt/emcomm-tools/bin/et-modem73 index bb32d1c..1f92e51 100755 --- a/overlay/opt/emcomm-tools/bin/et-modem73 +++ b/overlay/opt/emcomm-tools/bin/et-modem73 @@ -13,49 +13,56 @@ MODEM73_CONF_FILE="${HOME}/.config/modem73/settings" usage() { - echo "usage: $(basename $0) " - echo " " - echo " start - Start modem73 in selected mode" - echo " update-config - Update configuration for selected mode" + echo "usage: $(basename $0) [options]" + echo " " + echo " reliability - Max reliability (Slower Speed) [BPSK]" + echo " balanced - Balanced (Reliability and Speed) [QPSK]" + echo " speed - Max speed (Lower Reliability) [8PSK]" echo "" - echo " " - echo " default - QPSK, normal frames, 1/2 code rate (recommended)" + echo " [options]" + echo " --headless - Run modem73 headless" } -if [[ $# -ne 2 ]]; then - usage - exit 1 -fi +HEADLESS="" +MODE="" -MODE=$2 -case "${MODE}" in - default) - et-log "Configuration updates not yet implemented." - ;; - *) - et-log "Can't started modem73. Mode '${MODE}' not supported" +for arg in "$@"; do + case "$arg" in + --headless) + HEADLESS="--headless" + ;; + reliability|balanced|speed) + if [[ -n "${MODE}" ]]; then + et-log "Only one mode may be specified." + usage + exit 1 + fi + MODE="$arg" + ;; + *) + echo "Unknown argument: $arg" + usage + exit 1 + ;; + esac +done + +if [[ -z "${MODE}" ]]; then + et-log "Can't started modem73. Mode not specified." usage exit 1 - ;; -esac +fi -notify_user() { - notify-send \ - -t 10000 \ - --app-name="EmComm Tools" \ - "$1" -} - -[ -z ${ET_LOG_DIR} ] && ET_LOG_DIR="${HOME}/.local/share/emcomm-tools" -[ ! -e ${ET_LOG_DIR} ] && mkdir -p ${ET_LOG_DIR} +[[ -z ${ET_LOG_DIR} ]] && ET_LOG_DIR="${HOME}/.local/share/emcomm-tools" +[[ ! -e ${ET_LOG_DIR} ]] && mkdir -p ${ET_LOG_DIR} start() { update_config - if [ $? -eq 0 ]; then + if [[ $? -eq 0 ]]; then systemctl is-active --quiet rigctld - if [ $? -ne 0 ]; then + if [[ $? -ne 0 ]]; then et-log "Can't start modem73. rigctld not running. Ensure radio is selected." notify_user "Can't start modem73. rigctld not running." exit 1 @@ -65,7 +72,7 @@ start() { INPUT_AUDIO=$(modem73 --list-audio | grep input | grep $ALSA_DEVICE | cut -d":" -f3) OUTPUT_AUDIO=$(modem73 --list-audio | grep output| grep $ALSA_DEVICE | cut -d":" -f3) - CMD="modem73 --input-device ${INPUT_AUDIO} --output-device ${OUTPUT_AUDIO} --ptt rigctl --headless" + CMD="modem73 --input-device ${INPUT_AUDIO} --output-device ${OUTPUT_AUDIO} --ptt rigctl ${HEADLESS}" et-log "Starting modem73 with: '${CMD}'" echo ${CMD} @@ -114,16 +121,4 @@ update_config () { } -case $1 in - start) - start - ;; - update-config) - update_config - ;; - *) - echo "Invalid command." - usage - exit 1 - ;; -esac +start From 832fc11c443a5bc1c6d3648f52a63379d442fb2f Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 30 Jun 2026 13:09:05 -0700 Subject: [PATCH 60/64] modem73 - Added support for passing the currently configured callsign --- overlay/opt/emcomm-tools/bin/et-modem73 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-modem73 b/overlay/opt/emcomm-tools/bin/et-modem73 index 1f92e51..972b605 100755 --- a/overlay/opt/emcomm-tools/bin/et-modem73 +++ b/overlay/opt/emcomm-tools/bin/et-modem73 @@ -25,6 +25,7 @@ usage() { HEADLESS="" MODE="" +CALLSIGN="N0CALL" for arg in "$@"; do case "$arg" in @@ -72,7 +73,7 @@ start() { INPUT_AUDIO=$(modem73 --list-audio | grep input | grep $ALSA_DEVICE | cut -d":" -f3) OUTPUT_AUDIO=$(modem73 --list-audio | grep output| grep $ALSA_DEVICE | cut -d":" -f3) - CMD="modem73 --input-device ${INPUT_AUDIO} --output-device ${OUTPUT_AUDIO} --ptt rigctl ${HEADLESS}" + CMD="modem73 --input-device ${INPUT_AUDIO} --output-device ${OUTPUT_AUDIO} --ptt rigctl --callsign ${CALLSIGN} ${HEADLESS}" et-log "Starting modem73 with: '${CMD}'" echo ${CMD} @@ -94,16 +95,16 @@ update_config () { et-log "Attempting to start modem73 in mode: '${MODE}'" - [ -z "$ET_USER_CONFIG" ] && ET_USER_CONFIG="${HOME}/.config/emcomm-tools/user.json" + [[ -z "$ET_USER_CONFIG" ]] && ET_USER_CONFIG="${HOME}/.config/emcomm-tools/user.json" CALLSIGN=$(cat ${ET_USER_CONFIG} | jq -r .callsign) # 1. Check if the symlink was created by the udev rules - if [ -e /dev/et-audio ]; then + if [[ -e /dev/et-audio ]]; then # 2. Check that this device was properly tagged with the ET_AUDIO env variable with a udev rule APLAY_OUT=$(arecord -l | grep ET_AUDIO) - if [ $? -eq 0 ]; then + if [[ $? -eq 0 ]]; then # Configure ALSA settings for sound card /opt/emcomm-tools/bin/et-audio update-config From a74e19b3cc56e8e8aae2dc8ee115e03d8c8f19ce Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 30 Jun 2026 13:32:51 -0700 Subject: [PATCH 61/64] modem73 - Added three more modulation types that map to fast speeds --- overlay/opt/emcomm-tools/bin/et-modem73 | 51 ++++++++++++++++++++----- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-modem73 b/overlay/opt/emcomm-tools/bin/et-modem73 index 972b605..dec6ac5 100755 --- a/overlay/opt/emcomm-tools/bin/et-modem73 +++ b/overlay/opt/emcomm-tools/bin/et-modem73 @@ -9,6 +9,18 @@ # # Postconditions: # 1. modem73 started with sane defaults +# +# Notes: +# +# modem73 supports many modulation types and configuration options. To +# keep usage simple, only five modulation settings have been configured +# that map to a combination of reliability and speed for most general +# purpose applications. +# +# In all cases, normal frames and 1/2 coding rate is used. +# +# There are faster speeds, but EmComm Tools has the design goal of +# getting the message through and favoring delivery over speed.. MODEM73_CONF_FILE="${HOME}/.config/modem73/settings" @@ -16,8 +28,10 @@ usage() { echo "usage: $(basename $0) [options]" echo " " echo " reliability - Max reliability (Slower Speed) [BPSK]" - echo " balanced - Balanced (Reliability and Speed) [QPSK]" - echo " speed - Max speed (Lower Reliability) [8PSK]" + echo " balanced - Balanced (Reliability and Speed) [QPSK] RECOMENDED" + echo " fast - Fast (Low Reliability) [8PSK]" + echo " faster - Faster (Lower Reliability) [QAM16]" + echo " fastest - Fastest (Lowest Reliability) [QAM64]" echo "" echo " [options]" echo " --headless - Run modem73 headless" @@ -25,6 +39,7 @@ usage() { HEADLESS="" MODE="" +MODE_ARGS="" CALLSIGN="N0CALL" for arg in "$@"; do @@ -32,7 +47,7 @@ for arg in "$@"; do --headless) HEADLESS="--headless" ;; - reliability|balanced|speed) + reliability|balanced|fast|faster|fastest) if [[ -n "${MODE}" ]]; then et-log "Only one mode may be specified." usage @@ -49,11 +64,29 @@ for arg in "$@"; do done if [[ -z "${MODE}" ]]; then - et-log "Can't started modem73. Mode not specified." - usage - exit 1 + et-log "Can't started modem73. Mode not specified." + usage + exit 1 fi +case "${MODE}" in + reliability) + MODE_ARGS="--modulation BPSK --normal --rate 1/2" + ;; + balanced) + MODE_ARGS="--modulation QPSK --normal --rate 1/2" + ;; + fast) + MODE_ARGS="--modulation 8PSK --normal --rate 1/2" + ;; + faster) + MODE_ARGS="--modulation QAM16 --normal --rate 1/2" + ;; + fastest) + MODE_ARGS="--modulation QAM64 --normal --rate 1/2" + ;; +esac + [[ -z ${ET_LOG_DIR} ]] && ET_LOG_DIR="${HOME}/.local/share/emcomm-tools" [[ ! -e ${ET_LOG_DIR} ]] && mkdir -p ${ET_LOG_DIR} @@ -73,12 +106,12 @@ start() { INPUT_AUDIO=$(modem73 --list-audio | grep input | grep $ALSA_DEVICE | cut -d":" -f3) OUTPUT_AUDIO=$(modem73 --list-audio | grep output| grep $ALSA_DEVICE | cut -d":" -f3) - CMD="modem73 --input-device ${INPUT_AUDIO} --output-device ${OUTPUT_AUDIO} --ptt rigctl --callsign ${CALLSIGN} ${HEADLESS}" - et-log "Starting modem73 with: '${CMD}'" + CMD="modem73 --input-device ${INPUT_AUDIO} --output-device ${OUTPUT_AUDIO} --ptt rigctl --callsign ${CALLSIGN} ${MODE_ARGS} ${HEADLESS}" + et-log "Starting modem73 in mode ${MODE} with: '${CMD}'" echo ${CMD} else - et-log "Error updating configuration. Can't start modem73" + et-log "Error configurating modem. Can't start modem73" exit 1 fi } From e0630fadb1ab43881e02757590b5c33eeeb65f3d Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 30 Jun 2026 13:45:18 -0700 Subject: [PATCH 62/64] modem73 - Added systemd user unit files for each support modulation provided by the et-modem73 wrapper script --- .../user/et-service-modem73-default.service | 5 +++-- .../user/et-service-modem73-fast.service | 20 +++++++++++++++++++ .../user/et-service-modem73-faster.service | 20 +++++++++++++++++++ .../user/et-service-modem73-fastest.service | 20 +++++++++++++++++++ .../et-service-modem73-reliability.service | 20 +++++++++++++++++++ overlay/opt/emcomm-tools/bin/et-modem73 | 2 +- 6 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 overlay/etc/skel/.config/systemd/user/et-service-modem73-fast.service create mode 100644 overlay/etc/skel/.config/systemd/user/et-service-modem73-faster.service create mode 100644 overlay/etc/skel/.config/systemd/user/et-service-modem73-fastest.service create mode 100644 overlay/etc/skel/.config/systemd/user/et-service-modem73-reliability.service diff --git a/overlay/etc/skel/.config/systemd/user/et-service-modem73-default.service b/overlay/etc/skel/.config/systemd/user/et-service-modem73-default.service index 8e7e4a6..a4f87a4 100644 --- a/overlay/etc/skel/.config/systemd/user/et-service-modem73-default.service +++ b/overlay/etc/skel/.config/systemd/user/et-service-modem73-default.service @@ -1,5 +1,6 @@ # Author : Gaston Gonzalez # Date : 28 June 2026 +# Updated : 30 June 2026 # Purpose : User systemd unit file for EmComm Tools that starts modem73 # : in a default configuration. # @@ -10,10 +11,10 @@ # Reload this config : systemctl --user daemon-reload [Unit] -Description=EmComm Tools modem73 default service +Description=EmComm Tools modem73 default service for balanced performance [Service] -ExecStart=/opt/emcomm-tools/bin/et-modem73 start default +ExecStart=/opt/emcomm-tools/bin/et-modem73 balanced --headless Restart=no [Install] diff --git a/overlay/etc/skel/.config/systemd/user/et-service-modem73-fast.service b/overlay/etc/skel/.config/systemd/user/et-service-modem73-fast.service new file mode 100644 index 0000000..1cc4664 --- /dev/null +++ b/overlay/etc/skel/.config/systemd/user/et-service-modem73-fast.service @@ -0,0 +1,20 @@ +# Author : Gaston Gonzalez +# Date : 30 June 2026 +# Purpose : User systemd unit file for EmComm Tools that starts modem73 +# : in a fast configuration. +# +# Usage: +# Check status : systemctl --user status et-service-modem73-fast +# Start service : systemctl --user start et-service-modem73-fast +# Stop service : systemctl --user stop et-service-modem73-fast +# Reload this config : systemctl --user daemon-reload + +[Unit] +Description=EmComm Tools modem73 service for fast performance + +[Service] +ExecStart=/opt/emcomm-tools/bin/et-modem73 fast --headless +Restart=no + +[Install] +WantedBy=multi-user.target diff --git a/overlay/etc/skel/.config/systemd/user/et-service-modem73-faster.service b/overlay/etc/skel/.config/systemd/user/et-service-modem73-faster.service new file mode 100644 index 0000000..8639953 --- /dev/null +++ b/overlay/etc/skel/.config/systemd/user/et-service-modem73-faster.service @@ -0,0 +1,20 @@ +# Author : Gaston Gonzalez +# Date : 30 June 2026 +# Purpose : User systemd unit file for EmComm Tools that starts modem73 +# : in a faster configuration. +# +# Usage: +# Check status : systemctl --user status et-service-modem73-faster +# Start service : systemctl --user start et-service-modem73-faster +# Stop service : systemctl --user stop et-service-modem73-faster +# Reload this config : systemctl --user daemon-reload + +[Unit] +Description=EmComm Tools modem73 service for faster performance + +[Service] +ExecStart=/opt/emcomm-tools/bin/et-modem73 faster --headless +Restart=no + +[Install] +WantedBy=multi-user.target diff --git a/overlay/etc/skel/.config/systemd/user/et-service-modem73-fastest.service b/overlay/etc/skel/.config/systemd/user/et-service-modem73-fastest.service new file mode 100644 index 0000000..b5cee20 --- /dev/null +++ b/overlay/etc/skel/.config/systemd/user/et-service-modem73-fastest.service @@ -0,0 +1,20 @@ +# Author : Gaston Gonzalez +# Date : 30 June 2026 +# Purpose : User systemd unit file for EmComm Tools that starts modem73 +# : in a fastest configuration. +# +# Usage: +# Check status : systemctl --user status et-service-modem73-fastest +# Start service : systemctl --user start et-service-modem73-fastest +# Stop service : systemctl --user stop et-service-modem73-fastest +# Reload this config : systemctl --user daemon-reload + +[Unit] +Description=EmComm Tools modem73 service for fastest performance + +[Service] +ExecStart=/opt/emcomm-tools/bin/et-modem73 fastest --headless +Restart=no + +[Install] +WantedBy=multi-user.target diff --git a/overlay/etc/skel/.config/systemd/user/et-service-modem73-reliability.service b/overlay/etc/skel/.config/systemd/user/et-service-modem73-reliability.service new file mode 100644 index 0000000..28a84ac --- /dev/null +++ b/overlay/etc/skel/.config/systemd/user/et-service-modem73-reliability.service @@ -0,0 +1,20 @@ +# Author : Gaston Gonzalez +# Date : 30 June 2026 +# Purpose : User systemd unit file for EmComm Tools that starts modem73 +# : in a reliability configuration. +# +# Usage: +# Check status : systemctl --user status et-service-modem73-reliability +# Start service : systemctl --user start et-service-modem73-reliability +# Stop service : systemctl --user stop et-service-modem73-reliability +# Reload this config : systemctl --user daemon-reload + +[Unit] +Description=EmComm Tools modem73 service for reliable performance + +[Service] +ExecStart=/opt/emcomm-tools/bin/et-modem73 reliability --headless +Restart=no + +[Install] +WantedBy=multi-user.target diff --git a/overlay/opt/emcomm-tools/bin/et-modem73 b/overlay/opt/emcomm-tools/bin/et-modem73 index dec6ac5..274ea50 100755 --- a/overlay/opt/emcomm-tools/bin/et-modem73 +++ b/overlay/opt/emcomm-tools/bin/et-modem73 @@ -28,7 +28,7 @@ usage() { echo "usage: $(basename $0) [options]" echo " " echo " reliability - Max reliability (Slower Speed) [BPSK]" - echo " balanced - Balanced (Reliability and Speed) [QPSK] RECOMENDED" + echo " balanced - Balanced (Reliability and Speed) [QPSK] RECOMMENDED" echo " fast - Fast (Low Reliability) [8PSK]" echo " faster - Faster (Lower Reliability) [QAM16]" echo " fastest - Fastest (Lowest Reliability) [QAM64]" From ad3f81e785816a1e9b1c4055a84b2c3cdac74609 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 30 Jun 2026 13:55:50 -0700 Subject: [PATCH 63/64] modem73 - Updated et-reticulum to support no simple operating modes --- overlay/opt/emcomm-tools/bin/et-reticulum | 26 ++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum index 576d60e..1d32c39 100755 --- a/overlay/opt/emcomm-tools/bin/et-reticulum +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -101,7 +101,11 @@ if [[ $? -eq 0 ]]; then HAS_MODEM73_CONFIG=`grep Modem73Interface ~/.reticulum/config` if [[ $? -eq 0 ]]; then - modem_options+=("modem73-default" "modem73 (HF/VHF/UHF)") + modem_options+=("modem73-reliability" "Max reliability (Slower Speed) [BPSK]") + modem_options+=("modem73-balanced" "Balanced (Reliability and Speed) [QPSK] RECOMENDED") + modem_options+=("modem73-fast" "Fast (Low Reliability) [8PSK]") + modem_options+=("modem73-faster" "Faster (Lower Reliability) [QAM16]") + modem_options+=("modem73-fastest" "Fastest (Lowest Reliability) [QAM64]") fi modem_choice=$(dialog \ @@ -132,10 +136,26 @@ if [[ $? -eq 0 ]]; then et-log "Starting 1200 baud packet modem" start_and_wait_for_service et-service-direwolf-simple ;; - modem73-default) - et-log "Starting modem73 with defaults" + modem73-reliability) + et-log "Starting modem73 in reliability mode" + start_and_wait_for_service et-service-modem73-reliability + ;; + modem73-balanced) + et-log "Starting modem73 in balanced mode" start_and_wait_for_service et-service-modem73-default ;; + modem73-fast) + et-log "Starting modem73 in fast mode" + start_and_wait_for_service et-service-modem73-fast + ;; + modem73-faster) + et-log "Starting modem73 in faster mode" + start_and_wait_for_service et-service-modem73-faster + ;; + modem73-fastest) + et-log "Starting modem73 in fastest mode" + start_and_wait_for_service et-service-modem73-fastest + ;; *) et-log "No modem specified" ;; From 5d83a7683436a4e69b4c67b5b3f78bc8bb151037 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Tue, 30 Jun 2026 14:00:46 -0700 Subject: [PATCH 64/64] modem73 - Updated et-reticulum to support all the new simple-to-use modem73 modes --- overlay/opt/emcomm-tools/bin/et-reticulum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/overlay/opt/emcomm-tools/bin/et-reticulum b/overlay/opt/emcomm-tools/bin/et-reticulum index 1d32c39..9d57456 100755 --- a/overlay/opt/emcomm-tools/bin/et-reticulum +++ b/overlay/opt/emcomm-tools/bin/et-reticulum @@ -112,7 +112,7 @@ if [[ $? -eq 0 ]]; then --clear \ --title "Reticulum Configuration" \ --menu "Select a modem" \ - 13 60 10 \ + 13 70 10 \ "${modem_options[@]}" \ 2>&1 >/dev/tty)