diff --git a/overlay/etc/skel/.config/JS8Call.ini b/overlay/etc/skel/.config/JS8Call.ini index 30e6484..f918f2b 100644 --- a/overlay/etc/skel/.config/JS8Call.ini +++ b/overlay/etc/skel/.config/JS8Call.ini @@ -17,7 +17,7 @@ Miles=true MyCall=N0CALL MyGrid=DM33 MyGroups=@@TTP,@@TTPNET -MyInfo=ETC R3 +MyInfo=ETC R5 Polling=1 PSKReporter=false PTTMethod=@Variant(\0\0\0\x7f\0\0\0\x1eTransceiverFactory::PTTMethod\0\0\0\0\xfPTT_method_CAT\0) diff --git a/overlay/etc/skel/.fldigi/fldigi_def.xml b/overlay/etc/skel/.fldigi/fldigi_def.xml new file mode 100644 index 0000000..0472d43 --- /dev/null +++ b/overlay/etc/skel/.fldigi/fldigi_def.xml @@ -0,0 +1,3457 @@ + + + +1 + + +1 + + +5 + + +1 + + +0 + + +20 + + +0 + + +5 + + +200 + + +1 + + +1 + + +1 + + +0 + + +0 + + +0 + + +0 + + +, + + +CW,BPSK-31,RTTY,, + + +1 + + +0 + + +0 + + +0 + + +1 + + +-60 + + +-6 + + +-3 + + +0 + + +0 + + +60 + + +1 + + +1 + + +8 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +0 + + +3000 + + +1500 + + +1500 + + +1500 + + +1 + + +100 + + +1 + + +0 + + +1 + + +0 + + +1 + + +0 + + +0 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +42 + + + + + +0 + + +0 + + +0 + + +0 + + + + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + + +<FREQ> + + + +4 + + +0 + + +0 + + +0 + + +1 + + +50 + + +0 + + +-30 + + +9 + + +0 + + +1 + + +15 + + +0 + + +50 + + +1500 + + +25 + + +9 + + +1 + + +1 + + +3 + + +450 + + +68 + + +0 + + +1.25 + + +0 + + +0 + + +0 + + +1 + + +0 + + +0 + + +0 + + +1 + + +72 + + +1 + + +0 + + +0 + + +0 + + +0 + + +0 + + + + + +0 + + +0 + + +0 + + +1 + + +0 + + +200 + + +1 + + +0 + + +0 + + +0 + + +1 + + +1 + + +1 + + +1 + + +1 + + +18 + + +15 + + +0 + + +15 + + +0 + + +24 + + +150 + + +2 + + +0.4 + + +0.6 + + +100 + + +1 + + +0 + + +0 + + +10 + + +5 + + +50 + + +1 + + +1 + + +3 + + +0 + + +1 + + +0 + + +2000 + + +4 + + +0.8 + + +4 + + +0 + + +18 + + +CW,, + + +0 + + +0 + + +0 + + +4 + + +4 + + +0 + + +100 + + +0 + + +0 + + +=~<>%+&{} + + +0 + + +20 + + +1 + + +0 + + +1 + + +1 + + +1 + + +1 + + +0 + + +1 + + +0 + + +1 + + +1 + + +0 + + +0 + + +0 + + +1 + + +245 + + +245 + + +30 + + +1225 + + +2205 + + +250 + + +120 + + +450 + + +2 + + +20 + + +0 + + +0 + + +1 + + +0 + + +1 + + +2 + + +2 + + +2 + + +8 + + +4 + + +0 + + +1 + + +1 + + +2 + + +2 + + +8 + + +4 + + +1 + + +0 + + +1 + + +2 + + +1 + + +K + + +5 + + +4 + + +0 + + +1 + + +1 + + +1 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + + + + +2 + + +K + + +1 + + +0 + + +5 + + +0 + + +1 + + +1 + + +1 + + +1 + + +4 + + +0 + + +0 + + +4 + + +2 + + +4.5 + + +3 + + +0 + + +0 + + +1 + + +cq cq cq de nocall + + +0 + + +0 + + +0 + + +6 + + +10 + + +1 + + +fsq_heard_log.txt + + +1 + + +fsq_audit_log.txt + + +1 + + +1 + + +1 + + +1 + + +ifkp_heard_log.txt + + +1 + + +ifkp_audit_log.txt + + +1 + + +1 + + +1 + + + + + +32 + + +1 + + +1 + + +8 + + +1 + + +1 + + +1 + + +0 + + +0 + + +0 + + +0 + + +4 + + +1 + + +0 + + +0 + + +0 + + +CQ + + +2 + + +0 + + +1 + + +1 + + +1 + + +1 + + +CW,BPSK-31,RTTY,, + + +1 + + +125 + + +1 + + +1 + + +0 + + + + + + + + +1 + + +0 + + +1 + + +0 + + +1 + + +, + + +1 + + +1 + + +0 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +/usr/local/bin/flmsg + + +dinner_bell + + +8 + + +0 + + +dinner_bell + + +8 + + +0 + + +2 + + +phone + + +7 + + +0 + + +beeboo + + +6 + + +0 + + +phone + + +7 + + +0 + + +rtty_bell + + +9 + + +50 + + +0 + + +0 + + +1 + + +0 + + +1 + + +25 + + +50 + + +0 + + +500 + + +1500 + + +1250 + + +1750 + + +0 + + +/home/gaston/.fldigi/ + + +0 + + +0 + + +0 + + +https://www.hamcall.net/ + + +https://www.hamqth.com/ + + +http://www.qrz.com/ + + +https://callook.info/ + + +0 + + + + + + + + + + + +0 + + +1 + + +http://www.eqsl.cc/qslcard/importADIF.cfm?ADIFdata= + + + + + + + + + + + + + + +0 + + +0 + + +1 + + +0 + + +1 + + + + + + + + +1 + + +1 + + + + + +15 + + +127.0.0.1 + + +9876 + + +0 + + +0 + + +1 + + +0 + + +0 + + +0 + + +0 + + +0 + + +1 + + +maclogger_udp_strings.txt + + +127.0.0.1 + + +1100 + + +1 + + +0 + + +0 + + +1 + + +0 + + +0 + + +0 + + +0 + + +1 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +1 + + +0 + + +0 + + +/dev/ttyS0 + + +localhost:4532 + + + + + +2 + + + + + +1 + + +2 + + +250 + + +1 + + +0 + + +0 + + +200 + + +/home/gaston/.fldigi/rig-not-assigned.xml + + +/dev/ttyS0 + + +1 + + +2 + + +0 + + +1 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +NONE + + +0 + + +GPIO-3 + + +0 + + +0 + + +0 + + +0 + + +0 + + +2 + + +10 + + +50 + + +200 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +2 + + +200 + + +5 + + +0 + + +0 + + +NONE + + +0 + + +1 + + +6 + + +50 + + +18 + + +0 + + +0 + + +1 + + +24 + + +0 + + +0 + + +2125 + + +2 + + +NONE + + +NONE + + +0 + + +0 + + +0 + + +0 + + +1 + + +1 + + +1 + + +1 + + +0 + + +0 + + +0 + + +{{ET_CALLSIGN}} + + + + + + + + +{{ET_GRID}} + + + + + + + + +1 + + + + + + + + +{{ET_PORTAUDIO_DEVICE}} + + +{{ET_PORTAUDIO_INDEX}} + + +{{ET_PORTAUDIO_DEVICE}} + + +{{ET_PORTAUDIO_INDEX}} + + +default + + +19 + + +0 + + + + + +1 + + +1 + + +0 + + +0 + + +-1 + + +1 + + +1 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +/home/gaston/.fldigi/logs/logbook.adif + + +0 + + +1 + + +1 + + +0 + + +1 + + +88 + + +63 + + +55 + + +53 + + +216 + + +1 + + +1 + + +1 + + +0 + + +0 + + +0 + + +120 + + +1 + + +3 + + +*,-.; + + + + + + + + +1 + + +1 + + +20 + + + + + + + + + + + + + + +5 + + + + + + + + + + + +0 + + +0 + + +CALL if (RSTr), if (LOCATOR), NAME, QTH + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +127.0.0.1 + + +20001 + + + + + +w3nr.ddns.net:7300::|dx.n8noe.us:7373::|w0mw.dynip.com:23::| + + +sans + + +0 + + +14 + + +sans + + +0 + + +14 + + + + + + + + + + + +Show DX + + +SH/DX + + +dxcm 2 + + + + + +dxcm 3 + + + + + +dxcm 4 + + + + + +dxcm 5 + + + + + +dxcm 6 + + + + + +dxcm 7 + + + + + +dxcm 8 + + + + + +1 + + +0 + + +0 + + +0 + + +1 + + +0.5 + + +1 + + +1 + + +0 + + +1 + + +0 + + +0 + + +-3 + + +0.2 + + +default.pal + + +1 + + +UTF-8 + + +0 + + +16 + + +1 + + +sans + + +0 + + +16 + + +sans + + +0 + + +12 + + +1 + + +sans + + +0 + + +16 + + +sans + + +0 + + +12 + + +sans + + +0 + + +12 + + +sans + + +0 + + +12 + + +sans + + +0 + + +gtk+ + + +0 + + +1 + + +4 + + +1 + + +1 + + +0 + + +0 + + +1 + + +2 + + +30 + + +25 + + +15 + + +sans + + +0 + + +14 + + +0 + + +127.0.0.1 + + +8421 + + +0 + + +127.0.0.1 + + +7362 + + +127.0.0.1 + + +7322 + + +127.0.0.1 + + +7342 + + +7343 + + +0 + + +1 + + +0 + + +0 + + +3 + + +0 + + +2 + + +1 + + +0 + + +0 + + +0 + + +0 + + +63 + + +10 + + +50 + + +15 + + +100 + + +10 + + +0 + + +3 + + +15 + + +15 + + +0 + + +127.0.0.1 + + +12345 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +report.pskreporter.info + + +4739 + + +0 + + + + + + + + +0 + + +1 + + +1 + + +800 + + +1900 + + +4000 + + +1 + + +5 + + +0.05 + + +15 + + +0 + + +30 + + +500 + + +10 + + +3 + + +1 + + +0 + + +0 + + +0 + + +http://tgftp.nws.noaa.gov/data/observations/metar/decoded/ + + +Connection: close + + +KMDQ + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +1 + + +0 + + +/home/gaston/.fldigi/kml/ + + + + + +10000 + + +0 + + +120 + + +2 + + +60 + + +100 + + +0 + + + + + + + + + + + + + + + + + + + + + + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +0 + + +22 + + +0 + + +0 + + +sans + + +0 + + +0 + + +16 + + +0 + + +0 + + +0 + + +60 + + +100 + + +2000 + + +4000 + + +500 + + +1 + + +1 + + +5 + + +1 + + +1 + + +3 + + +0 + + +0 + + +0 + + +0 + + +4 + + +20 + + +0 + + +0 + + +4 + + +0.95 + + +0 + + +10 + + +0 + + +1 + + +0 + + +0 + + +0 + + +0 + + +0 + + +1 + + +0 + + +2 + + +1 + + +1 + + +1 + + +1 + + diff --git a/overlay/etc/udev/rules.d/89-et-bg2fx-fx4cr.rules b/overlay/etc/udev/rules.d/89-et-bg2fx-fx4cr.rules new file mode 100644 index 0000000..c7d6817 --- /dev/null +++ b/overlay/etc/udev/rules.d/89-et-bg2fx-fx4cr.rules @@ -0,0 +1,23 @@ +# Author : Gaston Gonzalez +# Date : 18 September 2025 +# Purpose : udev rules for the FX-4CR by BG2FX +# +# Preconditions: +# 1. FX-4CR connected via USB cable +# +# Postconditions: +# 1. /dev/et-cat created +# 2. rigctld is started +# 3. /dev/et-audio created + +SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", ENV{ET_DEVICE}=="", \ + ACTION=="add", \ + ENV{ET_DEVICE}="FX-4CR", ENV{ET_SUBDEVICE}="CAT", GROUP="dialout", MODE="0660", SYMLINK+="et-cat", \ + RUN+="/usr/bin/systemctl start rigctld" + +# PROGRAM="/opt/emcomm-tools/sbin/udev-tester.sh digirig-mobile", \ +SUBSYSTEM=="sound", ATTRS{idVendor}=="4c4a", ATTRS{idProduct}=="4155", \ + ACTION=="add", \ + ENV{ET_DEVICE}="FX-4CR", \ + ATTR{id}="ET_AUDIO", \ + ENV{ET_SUBDEVICE}="AUDIO", GROUP="audio", MODE="0660", SYMLINK+="et-audio" diff --git a/overlay/opt/emcomm-tools/bin/et-audio b/overlay/opt/emcomm-tools/bin/et-audio index dc33bde..b7a4e05 100755 --- a/overlay/opt/emcomm-tools/bin/et-audio +++ b/overlay/opt/emcomm-tools/bin/et-audio @@ -2,14 +2,14 @@ # # Author : Gaston Gonzalez # Date : 31 October 2024 -# Updated : 31 May 2024 +# Updated : 26 September 2025 # Purpose : Configures ET audio device with sane defaults # # Preconditions # 1. Supported audio interface is connected and properly detected # # Postconditions -# 1. ASLA settings set on ET audio device +# 1. ALSA settings set on ET audio device usage() { echo "usage: $(basename $0) " @@ -50,6 +50,8 @@ update-config () { case ${ET_DEVICE_NAME} in "DIGIRIG_MOBILE") + # TODO: 92% is needed for the TX-500MP. Revisit approach for setting speaker + # out differently across radios definitions. # Unmute Speaker a set volume. Adjust if remote station can't decode you. Your TX controls. amixer -q -c ${AUDIO_CARD} sset Speaker Playback Switch 42% unmute # Unmute Mic @@ -97,6 +99,19 @@ update-config () { et-log "Applied amixer settings for ${ET_DEVICE_NAME}" ;; + "FX-4CR") + # Unmute the PCM and set the volume to 21% to get the full output power. This value is + # dependent on the settings defined for the FX-4CR in the et-radio notes. + amixer -q -c ${AUDIO_CARD} sset 'PCM' 31% unmute + + # Set "L/R Capture" to 55%. Adjust if you can't decode received audio. + amixer -q -c ${AUDIO_CARD} sset 'Mic' 67% unmute + + # Disable Auto Gain Control + amixer -q -c ${AUDIO_CARD} sset 'Auto Gain Control' mute + + et-log "Applied amixer settings for ${ET_DEVICE_NAME}" + ;; *) et-log "No ALSA configuration specified for this ET_DEVICE." ;; diff --git a/overlay/opt/emcomm-tools/bin/et-fldigi b/overlay/opt/emcomm-tools/bin/et-fldigi new file mode 100755 index 0000000..70d0e52 --- /dev/null +++ b/overlay/opt/emcomm-tools/bin/et-fldigi @@ -0,0 +1,201 @@ +#!/bin/bash +# +# Author : Gaston Gonzalez +# Date : 2 October 2025 +# Purpose : Wrapper script for starting fldigi with PnP support +# +# Preconditions +# 1. Supported radio and audio interface are connected and properly detected +# +# Postconditions +# 1. Stop all running EmComm Tools modes +# 2. fldigi core settings updated (e.g., CAT, audio, user config and ETC defaults) +# 3. fldigi started + +usage() { + echo "usage: $(basename $0) " + echo " start - Update config and start fldigi" + echo " update-config - Update config" +} + +if [[ $# -ne 1 ]]; then + usage + exit 1 +fi + +notify_user() { + notify-send \ + -t 5000 \ + --app-name="EmComm Tools" \ + "$1" +} + +start() { + /opt/emcomm-tools/bin/et-kill-all && update-config && /usr/local/bin/fldigi & +} + +update-config () { + + # 1. Check if the audio device 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 + 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 fldigi. No ET_AUDIO device detected." + exit 1 + fi + else + et-log "No ET_AUDIO device plugged in." + notify_user "Can't start fldigi. No supported audio device plugged in." + exit 1 + fi + + PORT_AUDIO_CONF=/tmp/conf.tmp + GEO_CONF=/tmp/geo.tmp + FLDIGI_CONF_DIR="${HOME}/.fldigi" + FLDIGI_CONF_FILE="${FLDIGI_CONF_DIR}/fldigi_def.xml" + + if [[ ! -e ${FLDIGI_CONF_DIR} ]]; then + et-log "${FLDIGI_CONF_DIR} does not exist. Creating it from template." + mkdir -v ${FLDIGI_CONF_DIR} + cp -v /etc/skel/.fldigi/fldigi_def.xml ${FLDIGI_CONF_DIR} + fi + + [ -z "$ET_USER_CONFIG" ] && ET_USER_CONFIG="${HOME}/.config/emcomm-tools/user.json" + + # clean up temporary config that may exist + [[ -e ${PORT_AUDIO_CONF} ]] && rm ${PORT_AUDIO_CONF} + + et-portaudio 2>/dev/null > ${PORT_AUDIO_CONF} + + if [[ $? -ne 0 ]]; then + et-log "No supported ET_AUDIO device found" + exit 1 + fi + + DEVICE=$(jq -r -e '.device' ${PORT_AUDIO_CONF}) + if [[ $? -ne 0 ]]; then + et-log "Error getting PulseAudio device name for ET_AUDIO device" + exit 1 + fi + + INDEX=$(jq -r -e '.index' ${PORT_AUDIO_CONF}) + if [[ $? -ne 0 ]]; then + et-log "Error getting PulseAudio device index for ET_AUDIO device" + exit 1 + fi + + ############################################## + # Map ALSA ET_AUDIO device to PortAudio device + ############################################## + et-log "Updating PortAudio device configuration..." + + sed -i "s|^.*|1|" ${FLDIGI_CONF_FILE} + + sed -i "s|^.*|${DEVICE}|" ${FLDIGI_CONF_FILE} + sed -i "s|^.*|${INDEX}|" ${FLDIGI_CONF_FILE} + + sed -i "s|^.*|${DEVICE}|" ${FLDIGI_CONF_FILE} + sed -i "s|^.*|${INDEX}|" ${FLDIGI_CONF_FILE} + + et-log "Using device '${DEVICE}' and device index '${INDEX}' for PortAudio configuration" + + + ################# + # Update callsign + ################# + et-log "Updating callsign configuration..." + CALLSIGN=$(jq -r -e '.callsign' ${ET_USER_CONFIG}) + + if [[ "${CALLSIGN}" = "N0CALL" ]]; then + et-log "Exiting early. No callsign set. Run: et-user." + exit 1 + fi + + et-log "Using callsign '${CALLSIGN}'" + sed -i "s|^.*|${CALLSIGN}|" ${FLDIGI_CONF_FILE} + + + ############################################### + # Update grid based on ETC geolocation services + ############################################### + et-log "Updating your grid square..." + curl -f -s "http://localhost:1981/api/geo/position" > ${GEO_CONF} + + if [[ $? -eq 0 ]]; then + GRID=$(jq -r -e '.position.gridSquare' ${GEO_CONF}) + if [[ $? -eq 0 ]]; then + et-log "Using grid square '${GRID}' for your location" + sed -i "s|^.*|${GRID}|" ${FLDIGI_CONF_FILE} + fi + fi + + [[ -e ${GEO_CONF} ]] && rm ${GEO_CONF} + + + ##################################################################### + # Configure CAT interface using Hamlib's rig control daemon (rigctld) + ##################################################################### + et-log "Updating CAT control configuration..." + + sed -i "s|^.*|1|" ${FLDIGI_CONF_FILE} + sed -i "s|^.*|2|" ${FLDIGI_CONF_FILE} + sed -i "s|^.*|1|" ${FLDIGI_CONF_FILE} + sed -i "s|^.*|localhost:4532|" ${FLDIGI_CONF_FILE} + + + ###################################### + # Enable Reed Soloman ID for RX and TX + ###################################### + et-log "Enabling Reed Soloman ID for RX/TX..." + + sed -i "s|^.*|1|" ${FLDIGI_CONF_FILE} + sed -i "s|^.*|1|" ${FLDIGI_CONF_FILE} + + + ########################### + # Modem configuration: MT63 + ########################### + et-log "Updating MT63 modem configuration..." + + sed -i "s|^.*|1|" ${FLDIGI_CONF_FILE} + + + ######################## + # Repeater configuration + ######################## + et-log "Updating settings for linked repeater systems..." + + # Key up for 2 seconds before transmitting tone. Needed for linked repeater systems. + sed -i "s|^.*|2|" ${FLDIGI_CONF_FILE} + + + ##################### + # NBEMS configuration + ##################### + et-log "Updating settings for NBEMS..." + + sed -i "s|^.*|1|" ${FLDIGI_CONF_FILE} + sed -i "s|^.*|/usr/local/bin/flmsg|" ${FLDIGI_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/bin/et-kill-all b/overlay/opt/emcomm-tools/bin/et-kill-all index b08e594..ed0b8b3 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 : 7 February 2025 +# Updated : 2 October 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. diff --git a/overlay/opt/emcomm-tools/conf/radios.d/bg2fx-fx4cr.json b/overlay/opt/emcomm-tools/conf/radios.d/bg2fx-fx4cr.json new file mode 100644 index 0000000..6c39035 --- /dev/null +++ b/overlay/opt/emcomm-tools/conf/radios.d/bg2fx-fx4cr.json @@ -0,0 +1,28 @@ +{ + "id": "bg2fx-fx4cr", + "vendor": "BG2FX", + "model": "FX-4CR", + "rigctrl": { + "id": "2031", + "baud": "115200", + "ptt": "RIG", + "conf": "data_bits=8,serial_handshake=None,stop_bits=1,rts_state=OFF", + "pttOnly": "false" + }, + "notes": [ + "Short press [PWR], then rotate AF knob until POW = 5.0", + "Toggle [SSB] button until both USB and DIG appear", + "Short press [M. V] until VFOA is displayed", + "Long press [MENU], rotate AF to BLUETOOTH, rotate TUNE and set to 0", + "Set radio volume to 50", + "Set mic gain to 50", + "Set alsamixer PCM to 21", + "Set alsamixer Mic to 55", + "Set alsamixer AGC to mm" + ], + "fieldNotes": [ + "Tested with FX-4CR firmware version: 1.7.3 (2025/09/01)", + "You must force the RTS control line to low for audio output to work with the PTT", + "This is handled with rts_state=OFF using the --set-conf argument of rigctld" + ] +} diff --git a/overlay/opt/emcomm-tools/conf/radios.d/lab599-tx500mp.json b/overlay/opt/emcomm-tools/conf/radios.d/lab599-tx500mp.json new file mode 100644 index 0000000..63331ac --- /dev/null +++ b/overlay/opt/emcomm-tools/conf/radios.d/lab599-tx500mp.json @@ -0,0 +1,20 @@ +{ + "id": "lab599-tx500mp", + "vendor": "Lab599", + "model": "TX-500MP (DigiRig Mobile)", + "rigctrl": { + "id": "2014", + "baud": "9600", + "ptt": "RTS", + "pttOnly": "false" + }, + "notes": [ + "1. Set MENU 36 CAT PROTOCOL = TS2000", + "2. Set MODE = DIGI", + "", + "Do not enable VOX on radio" + + ], + "fieldNotes": [ + ] +} diff --git a/overlay/opt/emcomm-tools/sbin/udev-tester.sh b/overlay/opt/emcomm-tools/sbin/udev-tester.sh index 9f60211..02fb7f9 100755 --- a/overlay/opt/emcomm-tools/sbin/udev-tester.sh +++ b/overlay/opt/emcomm-tools/sbin/udev-tester.sh @@ -1,7 +1,7 @@ #!/bin/bash # Author : Gaston Gonzalez # Date : 11 October 2024 -# Updated : 21 May 2025 +# Updated : 13 September 2025 # Purpose : Perform tests that can be used by the udev subsystem to aid # in rule development. This is intended to by used with the PROGRAM # directive inside of a udev rule. @@ -81,6 +81,11 @@ test_digirig_mobile() { exit 0 fi + if [[ "$ID" == "lab599-tx500mp" ]]; then + et-log "Old DigiRig Mobile detected for TX-500MP" + exit 0 + fi + fi exit 1 diff --git a/overlay/opt/emcomm-tools/sbin/wrapper-rigctld.sh b/overlay/opt/emcomm-tools/sbin/wrapper-rigctld.sh index 1c1b9ab..534dd99 100755 --- a/overlay/opt/emcomm-tools/sbin/wrapper-rigctld.sh +++ b/overlay/opt/emcomm-tools/sbin/wrapper-rigctld.sh @@ -2,13 +2,16 @@ # # Author : Gaston Gonzalez # Date : 9 October 2024 -# Updated : 31 May 2025 +# Updated : 26 September 2025 # Purpose : Wrapper startup/shutdown script around systemd/rigctld ET_HOME=/opt/emcomm-tools ACTIVE_RADIO="${ET_HOME}/conf/radios.d/active-radio.json" CAT_DEVICE=/dev/et-cat +# Additional configuration to pass to rigctld +SET_CONF="" + do_full_auto() { et-log "Found ET_DEVICE='${ET_DEVICE}'" @@ -95,8 +98,14 @@ start() { exit 0 fi + # Handle optional configuration settings + CONF=$(jq -e -r '.rigctrl.conf' "${ET_HOME}/conf/radios.d/active-radio.json") + if [[ $? -eq 0 ]]; then + SET_CONF="--set-conf=${CONF}" + fi + # Generate command - CMD="rigctld -m ${ID} -r ${CAT_DEVICE} -s ${BAUD} -P ${PTT} " + CMD="rigctld -m ${ID} -r ${CAT_DEVICE} -s ${BAUD} -P ${PTT} ${SET_CONF}" et-log "Starting rigctld with: ${CMD}" $CMD } diff --git a/overlay/usr/share/glib-2.0/schemas/90_ubuntu-settings.gschema.override b/overlay/usr/share/glib-2.0/schemas/90_ubuntu-settings.gschema.override index 13f00af..af23eb0 100644 --- a/overlay/usr/share/glib-2.0/schemas/90_ubuntu-settings.gschema.override +++ b/overlay/usr/share/glib-2.0/schemas/90_ubuntu-settings.gschema.override @@ -12,7 +12,7 @@ show-desktop-icons = false picture-uri = 'file:///usr/share/backgrounds/emcomm-tools-wallpaper.png' [org.gnome.shell] -favorite-apps = ['emcomm-tools.desktop', 'js8call.desktop', 'et-aircraft.desktop', 'org.gnome.Terminal.desktop', 'navit.desktop', 'min.desktop', 'org.gnome.Nautilus.desktop'] +favorite-apps = ['emcomm-tools.desktop', 'js8call.desktop', 'fldigi.desktop', 'et-aircraft.desktop', 'org.gnome.Terminal.desktop', 'navit.desktop', 'min.desktop', 'org.gnome.Nautilus.desktop'] last-selected-power-profile = 'performance' [org.gnome.system.location] diff --git a/scripts/install-et-portaudio.sh b/scripts/install-et-portaudio.sh new file mode 100755 index 0000000..8326164 --- /dev/null +++ b/scripts/install-et-portaudio.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# Author : Gaston Gonzalez +# Date : 2 October 2025 +# Purpose : Builds and installs et-portaudio +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="et-portaudio" +VERSION="1.0.0" +APP_AND_VERSION="${APP}-${VERSION}" +INSTALL_DIR="/opt/${APP_AND_VERSION}" +LINK_PATH="/opt/${APP}" + +et-log "Installing ${APP} ${VERSION}" + +CWD_DIR=`pwd` + +cd ../src/et-portaudio + +# Compile +make install + +[[ -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-fldigi.sh b/scripts/install-fldigi.sh new file mode 100755 index 0000000..6c4e4ce --- /dev/null +++ b/scripts/install-fldigi.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# Author : Gaston Gonzalez +# Date : 17 September 2025 +# Updated : 2 October 2025 +# Purpose : Builds and installs fldigi +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="fldigi" +VERSION="4.2.09" +APP_AND_VERSION="${APP}-${VERSION}" +GIT_TAG="v4.2.09" +GIT_URL="https://git.code.sf.net/p/fldigi/fldigi" +GIT_WORKSPACE="fldigi" +INSTALL_DIR="/opt/${APP_AND_VERSION}" +LINK_PATH="/opt/${APP}" + +et-log "Installing ${APP} ${VERSION}" + +CWD_DIR=`pwd` + +cd ${ET_SRC_DIR} +[[ ! -e ${GIT_WORKSPACE} ]] && git clone ${GIT_URL} ${GIT_WORKSPACE} + +cd ${GIT_WORKSPACE} +git checkout ${GIT_TAG} + +# Generate config script +autoreconf -i && ./configure --prefix=${INSTALL_DIR} + +# Compile +make + +# Install +make install + +[[ -e ${LINK_PATH} ]] && rm ${LINK_PATH} +ln -v -s ${INSTALL_DIR} ${LINK_PATH} + +stow -v -d /opt ${APP} -t /usr/local + +cd ${CWD} + +# Use wrapper script as launcher executable +sed -i 's|^Exec.*|Exec=/opt/emcomm-tools/bin/et-fldigi start|' /opt/fldigi/share/applications/fldigi.desktop + diff --git a/scripts/install.sh b/scripts/install.sh index 655e658..06e94f8 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -2,7 +2,7 @@ # # Author : Gaston Gonzalez # Date : 16 March 2024 -# Updated : 16 August 2025 +# Updated : 2 October 2025 # Purpose : Main installer for EmComm Tools Community (ETC) . ./env.sh @@ -87,3 +87,9 @@ exitIfNotRoot # Install prediction tools ./install-voacap.sh + +# Install fldigi suite +./install-fldigi.sh +./install-et-portaudio.sh + +# TODO: add installers for flmsg and flamp diff --git a/src/et-portaudio/.gitignore b/src/et-portaudio/.gitignore new file mode 100644 index 0000000..a75e2aa --- /dev/null +++ b/src/et-portaudio/.gitignore @@ -0,0 +1,2 @@ +et-portaudio +*.o diff --git a/src/et-portaudio/Makefile b/src/et-portaudio/Makefile new file mode 100644 index 0000000..61b64d4 --- /dev/null +++ b/src/et-portaudio/Makefile @@ -0,0 +1,25 @@ +CC = gcc +CFLAGS = -Wall -O2 +LDFLAGS = -lportaudio -lasound + +TARGET = et-portaudio +SRC = main.c +VERSION=1.0.0 +INSTALL_DIR = /opt/et-portaudio-$(VERSION)/bin + +.PHONY: install + +all: $(TARGET) + +$(TARGET): $(SRC) + $(CC) $(CFLAGS) -o $(TARGET) $(SRC) $(LDFLAGS) + +install: $(TARGET) + @echo "Installing $(TARGET) to $(INSTALL_DIR)..." + @mkdir -p $(INSTALL_DIR) + @cp $(TARGET) $(INSTALL_DIR)/ + @chmod 755 $(INSTALL_DIR)/$(TARGET) + @echo "Done." + +clean: + rm -f $(TARGET) *.o diff --git a/src/et-portaudio/README.md b/src/et-portaudio/README.md new file mode 100644 index 0000000..e4f6ac4 --- /dev/null +++ b/src/et-portaudio/README.md @@ -0,0 +1,32 @@ +# et-portaudio + +A utility program intended for script use to convert a supported +EmComm Tools ALSA audio device (i.e. `ET_AUDIO`) to a PulseAudio device. + +## Usage + +Returns a JSON object with the PulseAudio device details on success. + +```bash +./et-portaudio 2>/dev/null +{ + "device": "USB Audio Device: - (hw:1,0)", + "index": 6 +} +``` + +If no supported device is found or on error, the utility exits with an +exit status of 1. + + +## Build + +``bash +make +``` + +## Install + +```bash +sudo make install +``` diff --git a/src/et-portaudio/gen-fldigi-cfg.sh b/src/et-portaudio/gen-fldigi-cfg.sh new file mode 100755 index 0000000..9f85b8e --- /dev/null +++ b/src/et-portaudio/gen-fldigi-cfg.sh @@ -0,0 +1,147 @@ +#!/bin/bash +# Author : Gaston Gonzalez +# Date : 1 October 2025 +# Updated : 2 October 2025 +# Purpose : Temporary script to fast-fail dynamic fldigi config for PnP +# +# NOTE: THIS IS SCRIPT IS INTENDED FOR DEVELOPMENT OF THE PNP SOLUTION. + +CMD=et-portaudio +PORT_AUDIO_CONF=/tmp/conf.tmp +GEO_CONF=/tmp/geo.tmp +FLDIGI_CONF_DIR="${HOME}/.fldigi" +FLDIGI_CONF_FILE="${FLDIGI_CONF_DIR}/fldigi_def.xml" + +[ -z "$ET_USER_CONFIG" ] && ET_USER_CONFIG="${HOME}/.config/emcomm-tools/user.json" + +# clean up temporary config that may exist +[[ -e ${PORT_AUDIO_CONF} ]] && rm ${PORT_AUDIO_CONF} + +[[ ! -e ${CMD} ]] && make +./${CMD} 2>/dev/null > ${PORT_AUDIO_CONF} + +if [[ $? -ne 0 ]]; then + echo "No supported ET_AUDIO device found" + exit 1 +fi + +DEVICE=$(jq -r -e '.device' ${PORT_AUDIO_CONF}) +if [[ $? -ne 0 ]]; then + echo "Error getting PulseAudio device name for ET_AUDIO device" + exit 1 +fi + +INDEX=$(jq -r -e '.index' ${PORT_AUDIO_CONF}) +if [[ $? -ne 0 ]]; then + echo "Error getting PulseAudio device index for ET_AUDIO device" + exit 1 +fi + +################################ +# Bootstrap fldigi configuration +################################ +et-log "Checking for .fldigi directory" +[[ ! -e ${FLDIGI_CONF_DIR} ]] && mkdir -v ${FLDIGI_CONF_DIR} + +et-log "Copying fldigi template..." +cp -v ../../overlay/etc/skel/.fldigi/fldigi_def.xml ~/.fldigi/ + + +############################################## +# Map ALSA ET_AUDIO device to PortAudio device +############################################## +et-log "Updating PortAudio device configuration..." + +sed -i "s|^.*|1|" ${FLDIGI_CONF_FILE} + +sed -i "s|^.*|${DEVICE}|" ${FLDIGI_CONF_FILE} +sed -i "s|^.*|${INDEX}|" ${FLDIGI_CONF_FILE} + +sed -i "s|^.*|${DEVICE}|" ${FLDIGI_CONF_FILE} +sed -i "s|^.*|${INDEX}|" ${FLDIGI_CONF_FILE} + +et-log "Using device '${DEVICE}' and device index '${INDEX}' for PortAudio configuration" + + +################# +# Update callsign +################# +et-log "Updating callsign configuration..." +CALLSIGN=$(jq -r -e '.callsign' ${ET_USER_CONFIG}) + +if [[ "${CALLSIGN}" = "N0CALL" ]]; then + et-log "Exiting early. No callsign set. Run: et-user." + exit 1 +fi + +et-log "Using callsign '${CALLSIGN}'" +sed -i "s|^.*|${CALLSIGN}|" ${FLDIGI_CONF_FILE} + + +############################################### +# Update grid based on ETC geolocation services +############################################### +et-log "Updating your grid square..." +curl -f -s "http://localhost:1981/api/geo/position" > ${GEO_CONF} + +if [[ $? -eq 0 ]]; then + GRID=$(jq -r -e '.position.gridSquare' ${GEO_CONF}) + if [[ $? -eq 0 ]]; then + et-log "Using grid square '${GRID}' for your location" + sed -i "s|^.*|${GRID}|" ${FLDIGI_CONF_FILE} + fi +fi + +[[ -e ${GEO_CONF} ]] && rm ${GEO_CONF} + + +##################################################################### +# Configure CAT interface using Hamlib's rig control daemon (rigctld) +##################################################################### +et-log "Updating CAT control configuration..." + +sed -i "s|^.*|1|" ${FLDIGI_CONF_FILE} +sed -i "s|^.*|2|" ${FLDIGI_CONF_FILE} +sed -i "s|^.*|1|" ${FLDIGI_CONF_FILE} +sed -i "s|^.*|localhost:4532|" ${FLDIGI_CONF_FILE} + + +###################################### +# Enable Reed Soloman ID for RX and TX +###################################### +et-log "Enabling Reed Soloman ID for RX/TX..." + +sed -i "s|^.*|1|" ${FLDIGI_CONF_FILE} +sed -i "s|^.*|1|" ${FLDIGI_CONF_FILE} + + +########################### +# Modem configuration: MT63 +########################### +et-log "Updating MT63 modem configuration..." + +sed -i "s|^.*|1|" ${FLDIGI_CONF_FILE} + + +######################## +# Repeater configuration +######################## +et-log "Updating settings for linked repeater systems..." + +# Key up for 2 seconds before transmitting tone. Needed for linked repeater systems. +sed -i "s|^.*|2|" ${FLDIGI_CONF_FILE} + + +##################### +# NBEMS configuration +##################### +et-log "Updating settings for NBEMS..." + +sed -i "s|^.*|1|" ${FLDIGI_CONF_FILE} +sed -i "s|^.*|/usr/local/bin/flmsg|" ${FLDIGI_CONF_FILE} + +# TODO: Add flmsg to ETC installer +# TODO: Add flamp to ETC installer +# TODO: Revisit autostart configuration to start flamp +# TODO: Revisit TCP/IP configuration when porting ETC R2 Build 56 +# TODO: Define TTP/ETC macros diff --git a/src/et-portaudio/main.c b/src/et-portaudio/main.c new file mode 100644 index 0000000..76aabfc --- /dev/null +++ b/src/et-portaudio/main.c @@ -0,0 +1,89 @@ +/* + * Author : Gaston Gonzalez + * Date : 1 October 2025 + * Purpose : Maps an ET_AUDIO ALSA device to a PortAudio device. + * + * This utility enumerates all ALSA audio devices using PortAudio + * to identify a currently plugged-in ET_AUDIO device. If a matching + * device is found, it generates a JSON object on STDOUT containing: + * + * - PortAudio device name + * - PortAudio device index + * + * Exit Status: + * 0 - ET_AUDIO device found and JSON output generated successfully + * 1 - ET_AUDIO device not found + */ + +#include +#include +#include +#include "portaudio.h" + +#define PROC_ALSA_PATH_FMT "/proc/asound/card%d/id" + +// Read the ALSA card ID from the /proc filesystem +int get_alsa_card_id(int card, char *id_buf, size_t buf_size) { + char path[64]; + snprintf(path, sizeof(path), PROC_ALSA_PATH_FMT, card); + FILE *f = fopen(path, "r"); + if (!f) return -1; + if (!fgets(id_buf, buf_size, f)) { + fclose(f); + return -1; + } + id_buf[strcspn(id_buf, "\n")] = 0; + fclose(f); + + return 0; +} + +int main(void) { + PaError err; + int i, numDevices; + const PaDeviceInfo *deviceInfo; + const PaHostApiInfo *hostApiInfo; + int found = 0; + + err = Pa_Initialize(); + if (err != paNoError) { + fprintf(stderr, "PortAudio error: %s\n", Pa_GetErrorText(err)); + return 1; + } + + numDevices = Pa_GetDeviceCount(); + if (numDevices < 0) { + fprintf(stderr, "No audio devices found"); + Pa_Terminate(); + return 1; + } + + for (i = 0; i < numDevices; i++) { + deviceInfo = Pa_GetDeviceInfo(i); + hostApiInfo = Pa_GetHostApiInfo(deviceInfo->hostApi); + + // Only show ALSA devices + if (hostApiInfo && strcmp(hostApiInfo->name, "ALSA") == 0) { + int card = -1, device = -1; + + // Extract ALSA card and device (hw:X,Y) + if (sscanf(deviceInfo->name, "%*[^()](hw:%d,%d)", &card, &device) == 2) { + char card_id[64]; + if (get_alsa_card_id(card, card_id, sizeof(card_id)) == 0) { + + // Only print if card ID matches ET_AUDIO + if (strcmp(card_id, "ET_AUDIO") == 0) { + found = 1; + printf("{\n"); + printf(" \"device\": \"%s\",\n", deviceInfo->name); + printf(" \"index\": %d\n", i); + printf("}\n"); + } + } + } + } + } + + Pa_Terminate(); + return found ? 0 : 1; +} diff --git a/tests/test-et-portaudio.sh b/tests/test-et-portaudio.sh new file mode 100755 index 0000000..d82bdcf --- /dev/null +++ b/tests/test-et-portaudio.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# Author : Gaston Gonzalez +# Date : 2 October 2025 +# Purpose : Test et-portaudio installation + +OUT=$(which et-portaudio) +exit $? diff --git a/tests/test-fldigi.sh b/tests/test-fldigi.sh new file mode 100755 index 0000000..8cb4197 --- /dev/null +++ b/tests/test-fldigi.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# Author : Gaston Gonzalez +# Date : 2 October 2025 +# Purpose : Test fldigi installation + +OUT=$(which fldigi) +exit $?