From 9c6dfb3e353b44c761f174d9798807a9983f330f Mon Sep 17 00:00:00 2001 From: Craig McDaniel Date: Fri, 20 Feb 2026 19:28:58 -0600 Subject: [PATCH] many updates not useful message --- ansible/playbooks/scanner/scanner.yml | 21 +++-- ansible/roles/scanner_digirig/tasks/main.yml | 87 ++++++++++++++++++- .../templates/digirig-direwolf.conf.j2 | 5 +- .../templates/digirig-direwolf.service.j2 | 2 +- .../templates/digirig-direwolf.sh | 24 ++--- ansible/roles/scanner_ft991a/tasks/main.yml | 14 ++- .../templates/ft991a-direwolf-hf.conf.j2 | 13 ++- .../templates/ft991a-direwolf-uhf.conf.j2 | 13 ++- .../templates/ft991a-direwolf-vhf.conf.j2 | 13 ++- .../templates/ft991a-direwolf.service.j2 | 6 +- .../templates/ft991a_monitor.py | 6 ++ .../roles/scanner_pat/tasks/config.json.j2 | 26 +++--- ansible/roles/scanner_pat/tasks/main.yml | 1 - .../scanner_pat/templates/config.json.j2 | 14 +-- orchestrate/ansible.sh | 39 ++++++--- 15 files changed, 207 insertions(+), 77 deletions(-) diff --git a/ansible/playbooks/scanner/scanner.yml b/ansible/playbooks/scanner/scanner.yml index 11f5703..6b748b6 100644 --- a/ansible/playbooks/scanner/scanner.yml +++ b/ansible/playbooks/scanner/scanner.yml @@ -7,22 +7,27 @@ become: true gather_facts: true tasks: - - name: Hamlib + - name: Set up base AX.25 stack with Digirig and dedicated VHF radio ansible.builtin.import_role: - name: hamlib - when: run_hamlib is defined and run_hamlib | bool + name: scanner_digirig + when: run_ax25 is defined and run_ax25 | bool + + - name: Set up base AX.25 stack with Digirig and dedicated VHF radio + ansible.builtin.import_role: + name: scanner_airspy_aprs + when: run_airspy_aprs is defined and run_airspy_aprs | bool - name: Set up udev rules, rigctld and direwolf for Yaesu FT991-A ansible.builtin.import_role: name: scanner_ft991a when: run_ft991a is defined and run_ft991a | bool - - name: Set up udev rules, rigctld and direwolf for Digirig digital sound card - ansible.builtin.import_role: - name: scanner_digirig - when: run_digirig is defined and run_digirig | bool - - name: Pat ansible.builtin.import_role: name: scanner_pat when: run_pat is defined and run_pat | bool + + - name: Hamlib + ansible.builtin.import_role: + name: hamlib + when: run_hamlib is defined and run_hamlib | bool diff --git a/ansible/roles/scanner_digirig/tasks/main.yml b/ansible/roles/scanner_digirig/tasks/main.yml index a20c047..aee84cd 100644 --- a/ansible/roles/scanner_digirig/tasks/main.yml +++ b/ansible/roles/scanner_digirig/tasks/main.yml @@ -43,8 +43,24 @@ group: root validate: '/usr/sbin/visudo -cf %s' +- name: Install AX.25 and NET/ROM packages + ansible.builtin.apt: + name: + - ax25-tools + - ax25-apps + - libax25 + state: present + +- name: Ensure AX.25 and NET/ROM kernel modules are loaded + community.general.modprobe: + name: "{{ item }}" + state: present + with_items: + - ax25 + - netrom + ################################################################################################### -# AX.25 BASH / DIREWOLF +# Direwolf bash script and config ################################################################################################### - name: Copy digirig-direwolf.sh AX.25 stack script @@ -62,9 +78,8 @@ owner: busnet group: busnet - ################################################################################################### -# SYSTEMD +# SYSTEMD: Direwolf ################################################################################################### - name: Copy AX.25 bash script to start direwolf and utils @@ -90,7 +105,71 @@ enabled: true ################################################################################################### -# UDEV RULES +# SYSTEMD: Net/Rom +################################################################################################### + +- name: Copy mheardd and netromd systemd service files + ansible.builtin.copy: + src: "templates/{{ item }}" + dest: "/etc/systemd/system/{{ item }}" + owner: root + group: root + mode: '0644' + with_items: + - mheardd.service + - netromd.service + register: services_copied + +- name: Enable and start AX.25/NET/ROM daemons + ansible.builtin.systemd: + name: "{{ item }}" + enabled: true + state: started + daemon_reload: "{{ services_copied.changed }}" + with_items: + - mheardd + - netromd + +################################################################################################### +# SYSTEMD: NET/ROM network interface init +# These get created when the service starts and they just stay running until you shut down the +# service or reboot. +################################################################################################### + +- name: Install systemd unit file for NET/ROM network interfaces + ansible.builtin.copy: + src: "templates/netrom-init.service.j2" + dest: "/etc/systemd/system/netrom-init.service" + owner: root + group: root + mode: '0644' + register: netrom_init_service + +- name: Enable and start netrom-init service + ansible.builtin.systemd: + name: netrom-init + enabled: true + state: started + daemon_reload: "{{ netrom_init_service.changed }}" + +################################################################################################### +# AX35 and NET/ROM Config +################################################################################################### + +- name: Copy AX.25 and NET/ROM static configuration files + ansible.builtin.copy: + src: "templates/{{ item }}" + dest: "/etc/ax25/{{ item }}" + owner: root + group: root + mode: '0644' + with_items: + - axports + - nrports + - nrbroadcast + +################################################################################################### +# UDEV RULES (keep these last) ################################################################################################### - name: Copy udev rules for the Digirig USB sound card diff --git a/ansible/roles/scanner_digirig/templates/digirig-direwolf.conf.j2 b/ansible/roles/scanner_digirig/templates/digirig-direwolf.conf.j2 index a17dd0f..aa08aaf 100644 --- a/ansible/roles/scanner_digirig/templates/digirig-direwolf.conf.j2 +++ b/ansible/roles/scanner_digirig/templates/digirig-direwolf.conf.j2 @@ -19,7 +19,4 @@ MODEM 1200 FX25TX 1 AGWPORT 8000 -KISSPORT 8001 - -# In the future, I might set up a RV BBS! I would beacon it here. -#PBEACON every=1 overlay=S symbol="bus" lat=29.958260914551104 long=-90.05442788530239 comment="I'm like testing APRS, man" via=WIDE1-1,WIDE2-1 +KISSPORT 8001 \ No newline at end of file diff --git a/ansible/roles/scanner_digirig/templates/digirig-direwolf.service.j2 b/ansible/roles/scanner_digirig/templates/digirig-direwolf.service.j2 index c878620..50e98de 100644 --- a/ansible/roles/scanner_digirig/templates/digirig-direwolf.service.j2 +++ b/ansible/roles/scanner_digirig/templates/digirig-direwolf.service.j2 @@ -19,7 +19,7 @@ After=dev-radio-digirig\x2dsound.device [Service] Type=simple -ExecStart=/bin/bash /opt/busnet/direwolf/digirig-direwolf.sh +ExecStart=/opt/busnet/direwolf/digirig-direwolf.sh Restart=on-failure RestartSec=5 User=busnet diff --git a/ansible/roles/scanner_digirig/templates/digirig-direwolf.sh b/ansible/roles/scanner_digirig/templates/digirig-direwolf.sh index 6a8588a..552f96a 100644 --- a/ansible/roles/scanner_digirig/templates/digirig-direwolf.sh +++ b/ansible/roles/scanner_digirig/templates/digirig-direwolf.sh @@ -23,21 +23,25 @@ # | # | USB sound card # | -# +----|---------------------------------------------------------------------------+ -# | | This is your computer. The things in here are virtual components. | -# | | | -# | +-----------+ +-------+ +------------+ Linux kernel | -# | | Direwolf | <---> | Socat | <----> | Kissattach | <------> ax0 interface | -# | +-----------+ +-------+ +------------+ | -# | | -# +--------------------------------------------------------------------------------+ +# +----|----------------------------------------------------------------------------+ +# | | This is your computer. The things in here are virtual components. | +# | | | +# | +-----------+ +-------+ +------------+ Linux kernel | +# | | Direwolf | <---> | Socat | <----> | Kissattach | <------> ax0 interface | +# | +-----------+ +-------+ +------------+ / | | +# | | /--------+ | | +# | AGWPE port / | | +# | available for +---------------+ +------------------+ | +# | use | mheard daemon | | netromd: NET/ROM | | +# | +---------------+ | Daemoon. | | +# | +------------------+ | +# +---------------------------------------------------------------------------------+ # Configuration DIREWOLF_CMD="/usr/local/bin/direwolf -t 0 -X 1 -c /opt/busnet/direwolf/config/digirig.conf" SOCAT_CMD="/usr/bin/socat PTY,raw,echo=0,link=/dev/radio/digirig-tnc TCP4:127.0.0.1:8001" KISSATTACH_CMD="/usr/sbin/kissattach /dev/radio/digirig-tnc digirig" KISSPARAMS_CMD="kissparms -c 1 -p digirig" -INTERFACE_NAME="ax0" cleanup() { echo @@ -116,4 +120,4 @@ echo "All processes started. Monitoring via wait..." wait -n # If we get here, one of the processes died. -cleanup \ No newline at end of file +cleanup diff --git a/ansible/roles/scanner_ft991a/tasks/main.yml b/ansible/roles/scanner_ft991a/tasks/main.yml index 11f8984..e1ee301 100644 --- a/ansible/roles/scanner_ft991a/tasks/main.yml +++ b/ansible/roles/scanner_ft991a/tasks/main.yml @@ -75,10 +75,18 @@ # chdir: /opt/busnet/direwolf/source/build # target: install -- name: Copy ft991a_monitor.py auto frequency sensing script +#- name: Copy ft991a_monitor.py auto frequency sensing script +# copy: +# src: "templates/ft991a_monitor.py" +# dest: "/opt/busnet/direwolf/ft991a_monitor.py" +# owner: busnet +# group: busnet +# mode: "0755" + +- name: Copy ft991a-monitor.sh script copy: - src: "templates/ft991a_monitor.py" - dest: "/opt/busnet/direwolf/ft991a_monitor.py" + src: "templates/ft991a-monitor.sh" + dest: "/opt/busnet/direwolf/ft991a-monitor.sh" owner: busnet group: busnet mode: "0755" diff --git a/ansible/roles/scanner_ft991a/templates/ft991a-direwolf-hf.conf.j2 b/ansible/roles/scanner_ft991a/templates/ft991a-direwolf-hf.conf.j2 index 4be6960..a339bd8 100644 --- a/ansible/roles/scanner_ft991a/templates/ft991a-direwolf-hf.conf.j2 +++ b/ansible/roles/scanner_ft991a/templates/ft991a-direwolf-hf.conf.j2 @@ -10,8 +10,17 @@ # do not have to worry about what USB port or tty number is assigned when this radio is connected # to the computer. -# We can reference this audio device by name already. -ADEVICE plughw:CODEC,0 +# IF Direwolf uses the ALSA device directly, this would be the device name. However, we do not +# use ALSA any more because only one device at a time can use the audio device this way, and when +# Direwolf is running, it locks it. +#ADEVICE plughw:CODEC,0 + +# This are peusdo ALSA devices created by PulseAudio! PulseAudio controls the ALSA device and then +# create this fake ALSA device that is actually connected directly to PulseAudio. This way Pulse +# locks the ALSA device, but then Pulse allows many devices to use the FT991a sound card, even +# over the network. +# These are defined in /etc/asound.conf +ADEVICE ft991a-capture ft991a-playback # The custom udev rule makes this device available by name. PTT /dev/radio/ft991a-01 RTS diff --git a/ansible/roles/scanner_ft991a/templates/ft991a-direwolf-uhf.conf.j2 b/ansible/roles/scanner_ft991a/templates/ft991a-direwolf-uhf.conf.j2 index fd412bc..c80927a 100644 --- a/ansible/roles/scanner_ft991a/templates/ft991a-direwolf-uhf.conf.j2 +++ b/ansible/roles/scanner_ft991a/templates/ft991a-direwolf-uhf.conf.j2 @@ -10,8 +10,17 @@ # do not have to worry about what USB port or tty number is assigned when this radio is connected # to the computer. -# We can reference this audio device by name already. -ADEVICE plughw:CODEC,0 +# IF Direwolf uses the ALSA device directly, this would be the device name. However, we do not +# use ALSA any more because only one device at a time can use the audio device this way, and when +# Direwolf is running, it locks it. +#ADEVICE plughw:CODEC,0 + +# This are peusdo ALSA devices created by PulseAudio! PulseAudio controls the ALSA device and then +# create this fake ALSA device that is actually connected directly to PulseAudio. This way Pulse +# locks the ALSA device, but then Pulse allows many devices to use the FT991a sound card, even +# over the network. +# These are defined in /etc/asound.conf +ADEVICE ft991a-capture ft991a-playback # The custom udev rule makes this device available by name. PTT /dev/radio/ft991a-01 RTS diff --git a/ansible/roles/scanner_ft991a/templates/ft991a-direwolf-vhf.conf.j2 b/ansible/roles/scanner_ft991a/templates/ft991a-direwolf-vhf.conf.j2 index f26fbec..c960bad 100644 --- a/ansible/roles/scanner_ft991a/templates/ft991a-direwolf-vhf.conf.j2 +++ b/ansible/roles/scanner_ft991a/templates/ft991a-direwolf-vhf.conf.j2 @@ -10,8 +10,17 @@ # do not have to worry about what USB port or tty number is assigned when this radio is connected # to the computer. -# We can reference this audio device by name already. -ADEVICE plughw:CODEC,0 +# IF Direwolf uses the ALSA device directly, this would be the device name. However, we do not +# use ALSA any more because only one device at a time can use the audio device this way, and when +# Direwolf is running, it locks it. +#ADEVICE plughw:CODEC,0 + +# This are peusdo ALSA devices created by PulseAudio! PulseAudio controls the ALSA device and then +# create this fake ALSA device that is actually connected directly to PulseAudio. This way Pulse +# locks the ALSA device, but then Pulse allows many devices to use the FT991a sound card, even +# over the network. +# These are defined in /etc/asound.conf +ADEVICE ft991a-capture ft991a-playback # The custom udev rule makes this device available by name. PTT /dev/radio/ft991a-01 RTS diff --git a/ansible/roles/scanner_ft991a/templates/ft991a-direwolf.service.j2 b/ansible/roles/scanner_ft991a/templates/ft991a-direwolf.service.j2 index 0726528..6911087 100644 --- a/ansible/roles/scanner_ft991a/templates/ft991a-direwolf.service.j2 +++ b/ansible/roles/scanner_ft991a/templates/ft991a-direwolf.service.j2 @@ -18,9 +18,6 @@ After=dev-radio-ft991a\x2d01.device [Service] ExecStartPre=/bin/sleep 5 -# This no longer starts Direwolf directly. See below. -#ExecStart=/usr/local/bin/direwolf -t 0 -X 1 -c /opt/busnet/direwolf/config/ft991a.conf - # This custom Python script connects to the rigctld daemon for the 991a and polls it every 5 seconds # to determine what frequency it is set on. If set on HF frequencies, it runs direwolf with a HF # config file for HF packet settings (300 baud). For VHF, it uses 1200 baud in a separate config file, @@ -28,7 +25,8 @@ ExecStartPre=/bin/sleep 5 # # This is automatic. All you have to do is switch the frequency on the 991a and this detects that and # stops/starts Direwolf with the matching packet configuration. -ExecStart=/opt/busnet/direwolf/ft991a_monitor.py +ExecStart=/opt/busnet/direwolf/ft991a-monitor.sh +#ExecStart=/opt/busnet/direwolf/ft991a_monitor.py Restart=on-failure RestartSec=5 diff --git a/ansible/roles/scanner_ft991a/templates/ft991a_monitor.py b/ansible/roles/scanner_ft991a/templates/ft991a_monitor.py index 29096af..fa283a1 100644 --- a/ansible/roles/scanner_ft991a/templates/ft991a_monitor.py +++ b/ansible/roles/scanner_ft991a/templates/ft991a_monitor.py @@ -1,6 +1,12 @@ #!/usr/bin/env python3 # @author Craig McDaniel using Google Gemini LLM # +# +# *** THIS IS NOT USED *** +# This was an early version of the monitor script. It's been rewritten in bash. I might just +# delete this. +# +# # This script polls the Yeasu FT-991a by connecting to a running rigctld daemon and asking that # daemon what the current radio's frequency is. If the radio is in any HF frequency, it makes # sure Direwolf is running with a HF AX.25 configuration at 300 baud. If a VHF or UHF frequency diff --git a/ansible/roles/scanner_pat/tasks/config.json.j2 b/ansible/roles/scanner_pat/tasks/config.json.j2 index 3a0796a..98ca81d 100644 --- a/ansible/roles/scanner_pat/tasks/config.json.j2 +++ b/ansible/roles/scanner_pat/tasks/config.json.j2 @@ -1,7 +1,7 @@ { "mycall": "K0BIT", "secure_login_password": "RYMF4H", - "auxiliary_addresses": [], + "auxiliary_addresses": ["K0BIT-11"], "locator": "EL49XW", "auto_download_size_limit": -1, "service_codes": [ @@ -9,28 +9,23 @@ ], "http_addr": "[::]:8080", "motd": [ - "BusNet Pat Winlink Client for K0BIT" + "BusNet Pat Winlink Client" ], "connect_aliases": { "telnet": "telnet://{mycall}:CMSTelnet@cms.winlink.org:8772/wl2k" }, - "listen": [], - "hamlib_rigs": {}, - "ax25": { + "hamlib_rigs": { + "ft-991a": {"address": "localhost:4000", "network": "tcp"} + }, + "ax25": { "engine": "linux", - "rig": "", - "beacon": { - "every": 0, - "message": "", - "destination": "" - } + "rig": "" }, "ax25_linux": { - "port": "wl2k" + "port": "digirig" }, "agwpe": { - "name: "Yaesu FT-991a", - "addr": "scanner.busnet:8011", + "addr": "scanner.busnet:8005", "radio_port": 0 }, "serial-tnc": { @@ -77,7 +72,8 @@ "enable_http": false, "allow_forms": false, "use_server_time": false, - "addr": "localhost:2947" + "update_locator": true, + "addr": "192.168.7.1:2947" }, "schedule": {}, "version_reporting_disabled": false diff --git a/ansible/roles/scanner_pat/tasks/main.yml b/ansible/roles/scanner_pat/tasks/main.yml index d53df7d..6dfc9ad 100644 --- a/ansible/roles/scanner_pat/tasks/main.yml +++ b/ansible/roles/scanner_pat/tasks/main.yml @@ -33,7 +33,6 @@ owner: busnet group: busnet - ################################################################################################### # SYSTEMD ################################################################################################### diff --git a/ansible/roles/scanner_pat/templates/config.json.j2 b/ansible/roles/scanner_pat/templates/config.json.j2 index e00f39e..2c6949e 100644 --- a/ansible/roles/scanner_pat/templates/config.json.j2 +++ b/ansible/roles/scanner_pat/templates/config.json.j2 @@ -1,7 +1,7 @@ { "mycall": "K0BIT", "secure_login_password": "RYMF4H", - "auxiliary_addresses": [], + "auxiliary_addresses": ["K0BIT-11"], "locator": "EL49XW", "auto_download_size_limit": -1, "service_codes": [ @@ -14,23 +14,15 @@ "connect_aliases": { "telnet": "telnet://{mycall}:CMSTelnet@cms.winlink.org:8772/wl2k" }, - "listen": [ - "ax25" - ], "hamlib_rigs": { "ft-991a": {"address": "localhost:4000", "network": "tcp"} }, "ax25": { "engine": "linux", - "rig": "", - "beacon": { - "every": 750, - "message": "This is my Pat Winlink client for P2P Winlink Email. Connect directly and send me a message.", - "destination": "IDENT" - } + "rig": "" }, "ax25_linux": { - "port": "digirig" + "port": "ax0" }, "agwpe": { "addr": "scanner.busnet:8005", diff --git a/orchestrate/ansible.sh b/orchestrate/ansible.sh index c493dcf..0a78f2b 100755 --- a/orchestrate/ansible.sh +++ b/orchestrate/ansible.sh @@ -30,10 +30,11 @@ show_help() echo echo "scanner.busnet:" echo "---------------------------------------------------------------------------------------------------------------" - echo " --scanner-digirig Set up udev rules, AX25, etc for the Digirig connected to the dedicated 2m radio" - echo " --scanner-ft991a Set up udev rules, rigctld and direwolf for the Yaesu FT-991a radio" - echo " --scanner-pat Install and configure pat winlink client on scanner.busnet" - echo " --scanner-hamlib Install and configure direwolf on scanner.busnet" + echo " --scanner-ax25 Set up base AX.25 stack with dedicated VHF radio with digirig, etc..." + echo " --scanner-airspy-aprs Set up AirSpy APRS receiver." + echo " --scanner-ft991a Set up udev rules, rigctld and direwolf for the Yaesu FT-991a radio." + echo " --scanner-pat Install and configure pat winlink client." + echo " --scanner-hamlib Install and configure direwolf." echo } @@ -51,8 +52,11 @@ main() elif [ "${COMMAND}" = "--build" ]; then ansible_build - elif [ "${COMMAND}" = "--scanner-digirig" ]; then - scanner_digirig + elif [ "${COMMAND}" = "--scanner-ax25" ]; then + scanner_ax25 + + elif [ "${COMMAND}" = "--scanner-airspy-aprs" ]; then + scanner_airspy_aprs elif [ "${COMMAND}" = "--scanner-ft991a" ]; then scanner_ft991a @@ -117,9 +121,9 @@ ansible_bootstrap_server() } -scanner_ft991a() +scanner_ax25() { - ansible_playbook playbooks/scanner/scanner.yml run_ft991a=1 + ansible_playbook playbooks/scanner/scanner.yml run_ax25=1 if [ $? != 0 ]; then echo echo "Ansible playbook execution failed." @@ -132,9 +136,24 @@ scanner_ft991a() } -scanner_digirig() +scanner_airspy_aprs() { - ansible_playbook playbooks/scanner/scanner.yml run_digirig=1 + ansible_playbook playbooks/scanner/scanner.yml run_airspy_aprs=1 + if [ $? != 0 ]; then + echo + echo "Ansible playbook execution failed." + echo + else + echo + echo "Ansible playbook execution complete." + echo + fi +} + + +scanner_ft991a() +{ + ansible_playbook playbooks/scanner/scanner.yml run_ft991a=1 if [ $? != 0 ]; then echo echo "Ansible playbook execution failed."