diff --git a/overlay/etc/skel/.config/systemd/user/et-service-winlink-native-packet.service b/overlay/etc/skel/.config/systemd/user/et-service-winlink-native-packet.service new file mode 100644 index 0000000..1241209 --- /dev/null +++ b/overlay/etc/skel/.config/systemd/user/et-service-winlink-native-packet.service @@ -0,0 +1,19 @@ +# Author : Gaston Gonzalez +# Date : 3 February 2025 +# Purpose : User systemd unit file for EmComm Tools Winlink over packet +# +# Usage: +# Check status : systemctl --user status et-service-winlink-native-packet +# Start service : systemctl --user start et-service-winlink-native-packet +# Stop service : systemctl --user stop et-service-winlink-native-packet +# Reload this config : systemctl --user daemon-reload + +[Unit] +Description=EmComm Tools Winlink native AX.25 packet service + +[Service] +ExecStart=/opt/emcomm-tools/bin/et-winlink start-native-packet +Restart=no + +[Install] +WantedBy=multi-user.target diff --git a/overlay/opt/emcomm-tools/bin/et-kill-all b/overlay/opt/emcomm-tools/bin/et-kill-all index 3182c39..cb1c84f 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 : 13 January 2025 +# Updated : 3 February 2025 # Purpose : Stops all EmComm Tools sound-based services (i.e. modems) and # amatuer radio applications to ensure a clean start for the next mode. @@ -11,6 +11,7 @@ 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-ardop systemctl --user stop et-service-direwolf-300 systemctl --user stop et-service-direwolf-9600 diff --git a/overlay/opt/emcomm-tools/bin/et-mode b/overlay/opt/emcomm-tools/bin/et-mode index b1e5862..2dd35d6 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 : 14 January 2025 +# Updated : 3 February 2025 # Purpose : Configures the system for a specific mode of operation # Use a simple text file to save the state of the last mode selected @@ -87,6 +87,18 @@ select_direwolf_mode () { fi } +select_winlink_mode () { + winlink_mode=() + + BLUETOOTH_TNC_CHECK=$(ps -ef | grep "[r]fcomm connect") + if [[ $? -eq 0 ]]; then + et-log "AX.25 over Bluetooth connected. Configuring Winlink for native AX.25" + start_and_wait_for_service et-service-winlink-native-packet + min http://localhost:8080 + exit 0 + fi +} + # Build list of options options=() options+=("${MODE_ID_NONE}" "No mode selected") @@ -150,11 +162,13 @@ if [ $exit_status -eq 0 ]; then et-log "Packet digipeater now running." ;; ${MODE_ID_WINLINK_ARDOP}) + et-log "Using ${PACKET_MODE} as the modem speed." start_and_wait_for_service et-service-ardop start_and_wait_for_service et-service-winlink-ardop min http://localhost:8080 ;; ${MODE_ID_WINLINK_PACKET}) + select_winlink_mode start_and_wait_for_service et-service-direwolf-simple start_and_wait_for_service et-service-winlink-packet min http://localhost:8080 diff --git a/overlay/opt/emcomm-tools/bin/et-radio b/overlay/opt/emcomm-tools/bin/et-radio index 5231894..5d81e5d 100755 --- a/overlay/opt/emcomm-tools/bin/et-radio +++ b/overlay/opt/emcomm-tools/bin/et-radio @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 11 October 2024 -# Updated : 14 December 2024 +# Updated : 3 February 2025 # Purpose : A script for managaing plug-and-play radios set -e @@ -48,6 +48,13 @@ if [ $exit_status -eq 0 ]; then VENDOR=$(cat ${ACTIVE_RADIO} | jq -r .vendor) MODEL=$(cat ${ACTIVE_RADIO} | jq -r .model) + BLUETOOTH_TNC_CHECK=$(ps -ef | grep "[r]fcomm connect") + if [[ $? -eq 0 ]]; then + et-log "Killing running processes for Bluetooth TNC" + sudo killall kissattach + sudo killall rfcomm + fi + printf "%-20s %-10s %-10s\n" "Radio ID" "Vendor" "Model" printf "%-20s %-10s %-10s\n\n" $ID "$VENDOR" "$MODEL" @@ -55,7 +62,6 @@ if [ $exit_status -eq 0 ]; then cat ${ACTIVE_RADIO} | jq -r '.notes[] | "* \(.)"' echo -e "${NC}" - printf "${GREEN}REQUIRED ACTIONS\n" printf "1. Apply the settings above to your radio.\n" printf "2. Plug in the USB cable for your radio. If it is already\n" diff --git a/overlay/opt/emcomm-tools/bin/et-uv-pro b/overlay/opt/emcomm-tools/bin/et-uv-pro index e54d76c..a883a41 100755 --- a/overlay/opt/emcomm-tools/bin/et-uv-pro +++ b/overlay/opt/emcomm-tools/bin/et-uv-pro @@ -2,14 +2,14 @@ # # Author : Gaston Gonzalez # Date : 1 January 2025 -# Updated : 3 January 2025 +# Updated : 3 February 2025 # Purpose : Utility for accessing the Bluetooth TNC on the BTECH # UV PRO. ACTIVE_RADIO="${ET_HOME}/conf/radios.d/btech-uvpro.bt.json" DEVICE_NAME="UV-PRO" BT_DEVICE="/dev/rfcomm0" -AX25_PORT="pkt1200" +AX25_PORT="wl2k" AX25_CONF_FILE="/etc/ax25/axports" ESC="\x1B" @@ -78,15 +78,15 @@ update_ax25_conf() { GREP_OUT=$(grep ${AX25_PORT} ${AX25_CONF_FILE}) if [ $? -eq 0 ]; then - # Delete all existing pkt1200 entries. Note: we can't use sed here + # Delete all existing AX.25 port entries. Note: we can't use sed here # since we do not have permission to create a temporary file with # inline replacement. ed modifies the file directly. - printf "g/^pkt1200/d\nw\nq\n" | ed ${AX25_CONF_FILE} > /dev/null 2>&1 + printf "g/^${AX25_PORT}/d\nw\nq\n" | ed ${AX25_CONF_FILE} > /dev/null 2>&1 fi info_message "Adding AX25 port for ${CALLSIGN}" - echo "pkt1200 ${CALLSIGN} 1200 255 2 1200 Packet" >> ${AX25_CONF_FILE} + echo "${AX25_PORT} ${CALLSIGN} 1200 255 2 1200 Packet" >> ${AX25_CONF_FILE} } stop_all_services() { @@ -235,8 +235,8 @@ EOF echo -e "${YELLOW}" echo -e "SAMPLE COMMANDS DESCRIPTION " echo -e "------------------------------- --------------------------------" - echo -e "axcall pkt1200 Connect directly to a node " - echo -e "axcall pkt1200 Connect to node via a digipeater" + echo -e "axcall ${AX25_PORT} Connect directly to a node " + echo -e "axcall ${AX25_PORT} Connect to node via a digipeater" echo -e "sudo axlisten -a -tttt -c Monitor inbound and outbound traffic" echo -e "${NC}" diff --git a/overlay/opt/emcomm-tools/bin/et-winlink b/overlay/opt/emcomm-tools/bin/et-winlink index cc3405c..783fe8e 100755 --- a/overlay/opt/emcomm-tools/bin/et-winlink +++ b/overlay/opt/emcomm-tools/bin/et-winlink @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 4 November 2024 -# Updated : 12 December 2024 +# Updated : 3 February 2025 # Purpose : Wrapper script for starting YAAC with PnP support # # Preconditions: @@ -13,14 +13,17 @@ # 1. Callsign, Winlink password, and grid are updated are updated # 2. pat http is started +source /opt/emcomm-tools/bin/et-common + PAT_CONF_FILE=${HOME}/.config/pat/config.json PAT_CONF_FILE_TEMPLATE=/etc/skel/.config/pat/config.json usage() { echo "usage: $(basename $0) " echo " " - echo " start-ardop - Start Pat Winlink in ardop mode" - echo " start-packet - Start Pat Winlink in packet mode" + echo " start-ardop - Start Pat Winlink in ardop mode" + echo " start-packet - Start Pat Winlink in packet mode" + echo " start-native-packet - Start Pat Winlink in native AX.25 packet mode" } if [ $# -ne 1 ]; then @@ -60,7 +63,7 @@ start_packet() { notify_user "Dire Wolf not running. Run: et-direwolf simple-packet" exit 1 fi - + update_config packet CMD="pat http" @@ -69,6 +72,24 @@ start_packet() { ${CMD} } +# Only the BTECH UV PRO is supported in this mode +start_native_packet() { + + BLUETOOTH_TNC_CHECK=$(ps -ef | grep "[r]fcomm connect") + if [[ $? -ne 0 ]]; then + echo -e "${RED}Can't start Pat in native AX.25 packet mode." + echo -e "If you have a UV Pro, first run: ${YELLOW}et-uv-pro connect${NC}" + exit 1 + fi + + update_config native-packet + + CMD="pat http" + et-log "Starting Pat with: ${CMD}" + + ${CMD} +} + update_config () { [ -z "$ET_USER_CONFIG" ] && ET_USER_CONFIG="${HOME}/.config/emcomm-tools/user.json" @@ -82,6 +103,18 @@ update_config () { exit 1 fi + case $1 in + ardop) + PAT_CONF_FILE_TEMPLATE=/opt/emcomm-tools/conf/template.d/winlink/config.ardop.json + ;; + packet) + PAT_CONF_FILE_TEMPLATE=/opt/emcomm-tools/conf/template.d/winlink/config.ax25-agw.json + ;; + native-packet) + PAT_CONF_FILE_TEMPLATE=/opt/emcomm-tools/conf/template.d/winlink/config.ax25-native.json + ;; + esac + et-log "Updating Pat configuration file: ${PAT_CONF_FILE}..." cp -v ${PAT_CONF_FILE_TEMPLATE} ${PAT_CONF_FILE} @@ -89,15 +122,6 @@ update_config () { sed -i "s|{{ET_WINLINK_PASSWD}}|${WINLINK_PASSWD}|g" ${PAT_CONF_FILE} sed -i "s|{{ET_GRID}}|${GRID}|g" ${PAT_CONF_FILE} - # Enable the P2P listener for the current mode selected (ARDOP or AX.25) - case $1 in - ardop) - sed -i "s|{{ET_WINLINK_LISTEN}}|ardop|g" ${PAT_CONF_FILE} - ;; - packet) - sed -i "s|{{ET_WINLINK_LISTEN}}|ax25|g" ${PAT_CONF_FILE} - ;; - esac } case $1 in @@ -107,6 +131,9 @@ case $1 in start-packet) start_packet ;; + start-native-packet) + start_native_packet + ;; *) echo "Invalid command." usage diff --git a/overlay/opt/emcomm-tools/conf/template.d/winlink/config.ardop.json b/overlay/opt/emcomm-tools/conf/template.d/winlink/config.ardop.json new file mode 100644 index 0000000..35bfb95 --- /dev/null +++ b/overlay/opt/emcomm-tools/conf/template.d/winlink/config.ardop.json @@ -0,0 +1,83 @@ +{ + "mycall": "{{ET_CALLSIGN}}", + "secure_login_password": "{{ET_WINLINK_PASSWD}}", + "auxiliary_addresses": [], + "locator": "{{ET_GRID}}", + "service_codes": [ + "PUBLIC" + ], + "http_addr": "localhost:8080", + "motd": [ + "Open source Winlink client - getpat.io" + ], + "connect_aliases": { + "telnet": "telnet://{mycall}:CMSTelnet@cms.winlink.org:8772/wl2k" + }, + "listen": [ "ardop" ], + "hamlib_rigs": { + "et-rig": { + "address": "localhost:4532", + "network": "tcp" + } + }, + "ax25": { + "engine": "agwpe", + "beacon": { + "every": 3600, + "message": "Winlink P2P", + "destination": "IDENT" + }, + "agwpe": {"addr": "localhost:8000", "radio_port": 0} + }, + "serial-tnc": { + "path": "/dev/ttyUSB0", + "serial_baud": 9600, + "hbaud": 1200, + "type": "Kenwood" + }, + "ardop": { + "addr": "localhost:8515", + "arq_bandwidth": { + "Forced": false, + "Max": 500 + }, + "rig": "et-rig", + "ptt_ctrl": true, + "beacon_interval": 0, + "cwid_enabled": true + }, + "pactor": { + "path": "/dev/ttyUSB0", + "baudrate": 57600, + "rig": "", + "custom_init_script": "" + }, + "telnet": { + "listen_addr": ":8774", + "password": "" + }, + "varahf": { + "host": "localhost", + "cmdPort": 8300, + "dataPort": 8301, + "bandwidth": 2300, + "rig": "", + "ptt_ctrl": false + }, + "varafm": { + "host": "localhost", + "cmdPort": 8300, + "dataPort": 8301, + "bandwidth": 0, + "rig": "", + "ptt_ctrl": false + }, + "gpsd": { + "enable_http": false, + "allow_forms": false, + "use_server_time": false, + "addr": "localhost:2947" + }, + "schedule": {}, + "version_reporting_disabled": false +} diff --git a/overlay/opt/emcomm-tools/conf/template.d/winlink/config.ax25-agw.json b/overlay/opt/emcomm-tools/conf/template.d/winlink/config.ax25-agw.json new file mode 100644 index 0000000..dc4caa4 --- /dev/null +++ b/overlay/opt/emcomm-tools/conf/template.d/winlink/config.ax25-agw.json @@ -0,0 +1,83 @@ +{ + "mycall": "{{ET_CALLSIGN}}", + "secure_login_password": "{{ET_WINLINK_PASSWD}}", + "auxiliary_addresses": [], + "locator": "{{ET_GRID}}", + "service_codes": [ + "PUBLIC" + ], + "http_addr": "localhost:8080", + "motd": [ + "Open source Winlink client - getpat.io" + ], + "connect_aliases": { + "telnet": "telnet://{mycall}:CMSTelnet@cms.winlink.org:8772/wl2k" + }, + "listen": [ "ax25" ], + "hamlib_rigs": { + "et-rig": { + "address": "localhost:4532", + "network": "tcp" + } + }, + "ax25": { + "engine": "agwpe", + "beacon": { + "every": 3600, + "message": "Winlink P2P", + "destination": "IDENT" + }, + "agwpe": {"addr": "localhost:8000", "radio_port": 0} + }, + "serial-tnc": { + "path": "/dev/ttyUSB0", + "serial_baud": 9600, + "hbaud": 1200, + "type": "Kenwood" + }, + "ardop": { + "addr": "localhost:8515", + "arq_bandwidth": { + "Forced": false, + "Max": 500 + }, + "rig": "et-rig", + "ptt_ctrl": true, + "beacon_interval": 0, + "cwid_enabled": true + }, + "pactor": { + "path": "/dev/ttyUSB0", + "baudrate": 57600, + "rig": "", + "custom_init_script": "" + }, + "telnet": { + "listen_addr": ":8774", + "password": "" + }, + "varahf": { + "host": "localhost", + "cmdPort": 8300, + "dataPort": 8301, + "bandwidth": 2300, + "rig": "", + "ptt_ctrl": false + }, + "varafm": { + "host": "localhost", + "cmdPort": 8300, + "dataPort": 8301, + "bandwidth": 0, + "rig": "", + "ptt_ctrl": false + }, + "gpsd": { + "enable_http": false, + "allow_forms": false, + "use_server_time": false, + "addr": "localhost:2947" + }, + "schedule": {}, + "version_reporting_disabled": false +} diff --git a/overlay/opt/emcomm-tools/conf/template.d/winlink/config.ax25-native.json b/overlay/opt/emcomm-tools/conf/template.d/winlink/config.ax25-native.json new file mode 100644 index 0000000..b39879d --- /dev/null +++ b/overlay/opt/emcomm-tools/conf/template.d/winlink/config.ax25-native.json @@ -0,0 +1,78 @@ +{ + "mycall": "{{ET_CALLSIGN}}", + "secure_login_password": "{{ET_WINLINK_PASSWD}}", + "auxiliary_addresses": [], + "locator": "{{ET_GRID}}", + "service_codes": [ + "PUBLIC" + ], + "http_addr": "localhost:8080", + "motd": [ + "Open source Winlink client - getpat.io" + ], + "connect_aliases": { + "telnet": "telnet://{mycall}:CMSTelnet@cms.winlink.org:8772/wl2k" + }, + "listen": [ "ax25" ], + "hamlib_rigs": { + }, + "ax25": { + "engine": "linux", + "beacon": { + "every": 3600, + "message": "Winlink P2P", + "destination": "IDENT" + }, + "ax25_linux": {"port": "wl2k"} + }, + "serial-tnc": { + "path": "/dev/ttyUSB0", + "serial_baud": 9600, + "hbaud": 1200, + "type": "Kenwood" + }, + "ardop": { + "addr": "localhost:8515", + "arq_bandwidth": { + "Forced": false, + "Max": 500 + }, + "ptt_ctrl": true, + "beacon_interval": 0, + "cwid_enabled": true + }, + "pactor": { + "path": "/dev/ttyUSB0", + "baudrate": 57600, + "rig": "", + "custom_init_script": "" + }, + "telnet": { + "listen_addr": ":8774", + "password": "" + }, + "varahf": { + "host": "localhost", + "cmdPort": 8300, + "dataPort": 8301, + "bandwidth": 2300, + "rig": "", + "ptt_ctrl": true + }, + "varafm": { + "host": "localhost", + "cmdPort": 8300, + "dataPort": 8301, + "bandwidth": 0, + "rig": "", + "ptt_ctrl": false + }, + "gpsd": { + "enable_http": false, + "allow_forms": false, + "use_server_time": false, + "addr": "localhost:2947" + }, + "schedule": {}, + "version_reporting_disabled": false +}