From 7b412c38e77323a496e83b38cf27f50679abd8f1 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Thu, 7 May 2026 05:34:48 -0700 Subject: [PATCH 01/67] debranding - Initial work to customize the Ubiquity installer --- .../ubiquity-slideshow/slides/et-predict.html | 15 ++++++ .../ubiquity-slideshow/slides/index.html | 44 ++++++++++++++++++ .../slides/links/background.png | Bin 0 -> 26488 bytes .../slides/screenshots/et-predict.png | Bin 0 -> 66085 bytes .../ubiquity-slideshow/slides/welcome.html | 15 ++++++ 5 files changed, 74 insertions(+) create mode 100644 overlay/usr/share/ubiquity-slideshow/slides/et-predict.html create mode 100644 overlay/usr/share/ubiquity-slideshow/slides/index.html create mode 100644 overlay/usr/share/ubiquity-slideshow/slides/links/background.png create mode 100644 overlay/usr/share/ubiquity-slideshow/slides/screenshots/et-predict.png create mode 100644 overlay/usr/share/ubiquity-slideshow/slides/welcome.html diff --git a/overlay/usr/share/ubiquity-slideshow/slides/et-predict.html b/overlay/usr/share/ubiquity-slideshow/slides/et-predict.html new file mode 100644 index 0000000..34f44ca --- /dev/null +++ b/overlay/usr/share/ubiquity-slideshow/slides/et-predict.html @@ -0,0 +1,15 @@ +

Offline HF Prediction

+ +
+ +
+ +
+

et-predict provides offline HF propagation prediction powered by VOACAP, helping operators take the guesswork out of establishing targeted contacts.

+
+ +
+ + + +
diff --git a/overlay/usr/share/ubiquity-slideshow/slides/index.html b/overlay/usr/share/ubiquity-slideshow/slides/index.html new file mode 100644 index 0000000..560c77d --- /dev/null +++ b/overlay/usr/share/ubiquity-slideshow/slides/index.html @@ -0,0 +1,44 @@ + + + + + + ubiquity-slideshow-ubuntu + + + + + + + + + + + + + + + + + +
+
+
+
+
+ +
+ + + +
+
+ + + + diff --git a/overlay/usr/share/ubiquity-slideshow/slides/links/background.png b/overlay/usr/share/ubiquity-slideshow/slides/links/background.png new file mode 100644 index 0000000000000000000000000000000000000000..8c17dd63cc8df34101b96d180684c15d4ab30140 GIT binary patch literal 26488 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

2jl zL#!j_NYCm~0>nFFiPA0ojIptn1#_dtOi^X7Le-gRAWqk{;k9sB2LIHYwHq5s^Wf}( z;6!8oqS*2dHI zv_T*72%=^6>;x`>1WyRl@w{@f&3ujA6_FIx?uPYF=xCMlQUSiidyy>mot8 zsmITt9rt$6Zzrxlw#OugkGWR!#_=S_X*$v zfF!aI{n!?+uIaNuof9&gCgiV|48JBsg?Z93J90o%{_PWsggsft1Y3h`O@e&7m^&V6 z{j)k(i;cLL*S_y=zKe8wWHS7(|N0Z96efW`Ha0c%00029Nkl+Y6@w>v~=}b|fM%p52A2N2D)P`b)_)hQ-R$VZl=)|lGQ;{Ug z52UJDwiXYECt>{EG|`^+1qF`okIz->--O2*{5wV>IRB3Hx090soATT!|O<{Q;GB7eW zATTsKG&VXgI3PhyAWc(LvTqU<0000bbVXQnWMOn=I%9HWVRU5xGB7eWEig4LFgH{& zF*-ChIxsjZFfckWFmtaw>;M1&C3HntbYx+4WjbwdWNBu305UK#HZ3qUEigA!F)=zc zHaajkD=;uRFfao0girtg02y>eSaefwW^{L9a%BK#Zf|X6EpuaXWo2%2Xm51y1HV21 O0000 literal 0 HcmV?d00001 diff --git a/overlay/usr/share/ubiquity-slideshow/slides/welcome.html b/overlay/usr/share/ubiquity-slideshow/slides/welcome.html new file mode 100644 index 0000000..f0287ec --- /dev/null +++ b/overlay/usr/share/ubiquity-slideshow/slides/welcome.html @@ -0,0 +1,15 @@ +

Welcome to EmComm Tools

+ +
+ +
+ +
+

Built for off-grid communications and field operations, EmComm Tools provides a ready-to-use environment focused on radio, preparedness, and resilient computing. Here are just a few of the tools and capabilities included in this release.

+
+ +
+ + + +
From a5fd8d959fc8d7dc3ef40e8e57b2b65142c0e5ed Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Thu, 7 May 2026 06:13:46 -0700 Subject: [PATCH 02/67] debranding - Added et-mail and et-aircraft to the slideshow --- .../ubiquity-slideshow/slides/et-aircraft.html | 15 +++++++++++++++ .../ubiquity-slideshow/slides/et-mail.html | 15 +++++++++++++++ .../share/ubiquity-slideshow/slides/index.html | 2 ++ .../slides/screenshots/et-aircraft.png | Bin 0 -> 109867 bytes .../slides/screenshots/et-mail.png | Bin 0 -> 30333 bytes 5 files changed, 32 insertions(+) create mode 100644 overlay/usr/share/ubiquity-slideshow/slides/et-aircraft.html create mode 100644 overlay/usr/share/ubiquity-slideshow/slides/et-mail.html create mode 100644 overlay/usr/share/ubiquity-slideshow/slides/screenshots/et-aircraft.png create mode 100644 overlay/usr/share/ubiquity-slideshow/slides/screenshots/et-mail.png diff --git a/overlay/usr/share/ubiquity-slideshow/slides/et-aircraft.html b/overlay/usr/share/ubiquity-slideshow/slides/et-aircraft.html new file mode 100644 index 0000000..217d429 --- /dev/null +++ b/overlay/usr/share/ubiquity-slideshow/slides/et-aircraft.html @@ -0,0 +1,15 @@ +

Offline Aircraft Tracking

+ +
+ +
+ +
+

et-aircraft provides offline aircraft tracking using supported SDRs like the RTL-SDR. There is no need for an Internet connection. Just plug in your SDR and click the airplane icon on the desktop.

+
+ +
+ + + +
diff --git a/overlay/usr/share/ubiquity-slideshow/slides/et-mail.html b/overlay/usr/share/ubiquity-slideshow/slides/et-mail.html new file mode 100644 index 0000000..f032f1a --- /dev/null +++ b/overlay/usr/share/ubiquity-slideshow/slides/et-mail.html @@ -0,0 +1,15 @@ +

Radio Email

+ +
+ +
+ +
+

et-mail provides a streamlined experience for radio based email by taking the guesswork out of which Winlink stations to connect to by incorporating real-time, offline HF prediction. It supports switching transport modes (AX.25, ardop, VARA) with zero configuration and without leaving the application.

+
+ +
+ + + +
diff --git a/overlay/usr/share/ubiquity-slideshow/slides/index.html b/overlay/usr/share/ubiquity-slideshow/slides/index.html index 560c77d..24e1917 100644 --- a/overlay/usr/share/ubiquity-slideshow/slides/index.html +++ b/overlay/usr/share/ubiquity-slideshow/slides/index.html @@ -30,6 +30,8 @@
+
+
diff --git a/overlay/usr/share/ubiquity-slideshow/slides/screenshots/et-aircraft.png b/overlay/usr/share/ubiquity-slideshow/slides/screenshots/et-aircraft.png new file mode 100644 index 0000000000000000000000000000000000000000..92e43692e189173f28340616b6a516e850512751 GIT binary patch literal 109867 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

q~uKKD78lRSG7kV-bz<497q%rYBEroE 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

3e8+wlgSp=jG(^5B@ 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 rw~N2T(brkQ)yvz{S;LPHbN2Gv=<1TyZIm4 literal 0 HcmV?d00001 From 2cc1eeac57ab5ce826eeb47e9bc6a7317ec528df Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 11 May 2026 06:42:51 -0700 Subject: [PATCH 03/67] debranding - Added initial support for branding EmComm Tools with basic Plymouth overrides. --- .../plymouth/themes/spinner/watermark.png | Bin 0 -> 3604 bytes scripts/debrand.sh | 24 ++++++++++++++++++ scripts/install.sh | 5 +++- 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 overlay/usr/share/plymouth/themes/spinner/watermark.png create mode 100755 scripts/debrand.sh diff --git a/overlay/usr/share/plymouth/themes/spinner/watermark.png b/overlay/usr/share/plymouth/themes/spinner/watermark.png new file mode 100644 index 0000000000000000000000000000000000000000..5eaadc5f62c33b0fe334b6a91f6d649c84a9c85c GIT binary patch literal 3604 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 NTf9B4#L6@Fe*kpB7-Ikc literal 0 HcmV?d00001 diff --git a/scripts/debrand.sh b/scripts/debrand.sh new file mode 100755 index 0000000..8de1229 --- /dev/null +++ b/scripts/debrand.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# Author : Gaston Gonzalez +# Date : 7 May 2026 +# Updated : 11 May 2026 +# Purpose : Debrand Ubuntu +# +# Post Conditions: +# 1. Plymouth splash screen displays on Live USB boot + +et-log "Debranding Ubuntu..." + +# A new kernel is required as the initramfs that Cubic uses is +# based on the base ISO by default. +et-log "Installing latest kernel..." +apt install \ + --reinstall \ + linux-headers-generic \ + linux-image-generic \ + -y + +# Note: Ensure you select the new kernel on the "Options" screen +# within your Cubic session. +et-log "Rebuilding initramfs..." +update-initramfs -uk all diff --git a/scripts/install.sh b/scripts/install.sh index eb807ae..e09c6fb 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 16 March 2024 -# Updated : 2 May 2026 +# Updated : 7 May 2026 # Purpose : Main installer for EmComm Tools Community (ETC) . ./env.sh @@ -118,3 +118,6 @@ exitIfNotRoot # Security Patches ./patch-copy-fail.sh + +# Debrand Ubuntu +./debrand.sh From 5ed346ad4ca1f50d98f740c0b085d55c730a14b1 Mon Sep 17 00:00:00 2001 From: thetechprepper Date: Mon, 11 May 2026 07:25:20 -0700 Subject: [PATCH 04/67] 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 05/67] 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 06/67] 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 07/67] 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 08/67] 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 09/67] 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 10/67] 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 11/67] 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 12/67] 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 13/67] 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 14/67] 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 15/67] 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 16/67] 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 17/67] 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 18/67] 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 19/67] 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 20/67] 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 21/67] 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 22/67] 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 23/67] 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 24/67] 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 25/67] 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 26/67] 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 27/67] 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 28/67] 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 29/67] 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 30/67] 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 31/67] 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 32/67] 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 33/67] 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 34/67] 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 35/67] 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 36/67] 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 37/67] 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 38/67] 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 39/67] 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 40/67] 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 41/67] 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 42/67] 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 43/67] 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 44/67] 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 45/67] 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 46/67] 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 47/67] 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 48/67] 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 49/67] 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 50/67] 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 51/67] 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 52/67] 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 53/67] 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 54/67] 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 55/67] 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 56/67] 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 57/67] 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 58/67] 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 59/67] 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 60/67] 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 61/67] 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 62/67] 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 63/67] 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 64/67] 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 65/67] 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 66/67] 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 67/67] 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)