diff --git a/LICENSE b/LICENSE index fe05cdf..abf30d6 100644 --- a/LICENSE +++ b/LICENSE @@ -29,7 +29,7 @@ you agree to the following terms and conditions: rights not expressly granted are reserved by The Tech Prepper LLC. For any inquiries regarding commercial use, modification, or other -permissions, please contact [Your Contact Information]. +permissions, please contact The Tech Prepper LLC. The Tech Prepper LLC info@thetechprepper.com diff --git a/overlay/etc/skel/.conkyrc b/overlay/etc/skel/.conkyrc index b22835a..54f6fdb 100644 --- a/overlay/etc/skel/.conkyrc +++ b/overlay/etc/skel/.conkyrc @@ -17,17 +17,25 @@ conky.config = { }; conky.text = [[ -${font DejaVu Sans Mono:size=12}${alignc}${time %A, %B %d %Y} +${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} Local: ${alignr}${time %H:%M:%S} UTC: ${alignr}${tztime UTC %H:%M:%S} -Uptime: ${uptime} -IP: ${execpi 60 /opt/emcomm-tools/bin/et-system-info ip} +${font DejaVu Sans:bold:size=10}${color #8d5133}${alignc}SYSTEM +${font DejaVu Sans Mono:size=11}${color yellow}Uptime : ${uptime} +CPU Util : ${cpu}% +Disk Free: ${fs_free /} -Radio: ${execpi 10 et-system-info active-radio} +${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:bold:size=10}${color #8d5133}${alignc}INTERFACES +${font DejaVu Sans Mono:size=11}${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} ${execpi 10 et-system-info et-audio-card} -${font DejaVu Sans Mono:size=10}${alignc}${execp /opt/emcomm-tools/bin/et-system-info release} +${font DejaVu Sans:bold:size=9}${color #805f4f}${alignc}${execp /opt/emcomm-tools/bin/et-system-info release} ]]; diff --git a/overlay/etc/udev/rules.d/79-et-generic-remove.rules b/overlay/etc/udev/rules.d/79-et-generic-remove.rules index d57933f..c9fa748 100644 --- a/overlay/etc/udev/rules.d/79-et-generic-remove.rules +++ b/overlay/etc/udev/rules.d/79-et-generic-remove.rules @@ -1,9 +1,10 @@ # Author : Gaston Gonzalez # Date : 14 October 2024 +# Updated : 24 October 2024 # Purpose : udev rules for generic remove events # # Preconditions: -# 1. CAT control device is unplugged +# 1. CAT control device (or DigiRig Lite) is unplugged # # Postconditions: # 1. rigctld is stopped @@ -11,3 +12,8 @@ SUBSYSTEM=="tty", ENV{ET_SUBDEVICE}=="CAT", \ ACTION=="remove", \ RUN+="/opt/emcomm-tools/sbin/wrapper-rigctld.sh stop" + + +SUBSYSTEM=="sound",ENV{ET_SUBDEVICE}=="AUDIO", \ + ACTION=="remove", \ + RUN+="/opt/emcomm-tools/sbin/wrapper-rigctld.sh stop" diff --git a/overlay/etc/udev/rules.d/80-et-ic705.rules b/overlay/etc/udev/rules.d/80-et-ic705.rules index f24e1f7..bbcadcc 100644 --- a/overlay/etc/udev/rules.d/80-et-ic705.rules +++ b/overlay/etc/udev/rules.d/80-et-ic705.rules @@ -1,6 +1,6 @@ # Author : Gaston Gonzalez # Date : 28 September 2024 -# Updated : 14 October 2024 +# Updated : 21 October 2024 # Purpose : udev rules for the Icom IC-705 # # Preconditions: @@ -9,6 +9,7 @@ # Postconditions: # 1. /dev/et-cat created # 2. /dev/et-gps created +# 3. /dev/et-audio created # 3. rigctld is started # 4. gpsd is started # @@ -32,4 +33,10 @@ ENV{ET_DEVICE}=="IC-705", SUBSYSTEMS=="usb", ATTRS{bInterfaceNumber}=="02", \ ENV{ET_SUBDEVICE}="GPS", GROUP="dialout", MODE="0660", SYMLINK+="et-gps", \ RUN+="/opt/emcomm-tools/sbin/wrapper-gpsd.sh start" -# TODO: Add rules for sound card +# This rule generically matches the following Icom radios: +# 1. IC-705 +# 2. IC-7200 +SUBSYSTEM=="sound", ATTRS{idVendor}=="08bb", ATTRS{idProduct}=="2901", ENV{ET_DEVICE}=="", \ + ACTION=="add", \ + ATTR{id}="ET_AUDIO", \ + ENV{ET_DEVICE}="Icom generic", ENV{ET_SUBDEVICE}="AUDIO", GROUP="audio", MODE="0660", SYMLINK+="et-audio" diff --git a/overlay/etc/udev/rules.d/81-et-ic7200.rules b/overlay/etc/udev/rules.d/81-et-ic7200.rules index 7669c9c..aa80239 100644 --- a/overlay/etc/udev/rules.d/81-et-ic7200.rules +++ b/overlay/etc/udev/rules.d/81-et-ic7200.rules @@ -1,6 +1,6 @@ # Author : Gaston Gonzalez # Date : 29 September 2024 -# Updated : 14 October 2024 +# Updated : 21 October 2024 # Purpose : udev rules for the Icom IC-7200 # # Preconditions: @@ -8,7 +8,8 @@ # # Postconditions: # 1. /dev/et-cat created -# 2. rigctld started +# 2. /dev/et-audio created +# 3. rigctld started KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", ATTRS{serial}=="IC-7200*", \ ENV{ET_DEVICE}="IC-7200" @@ -21,4 +22,10 @@ ENV{ET_DEVICE}=="IC-7200", SUBSYSTEMS=="usb", ATTRS{idVendor}=="10c4" ATTRS{idPr ENV{ET_SUBDEVICE}="CAT", GROUP="dialout", MODE="0660", SYMLINK+="et-cat", \ RUN+="/usr/bin/systemctl start rigctld" -# TODO: Add rules for sound card +# This rule generically matches the following Icom radios: +# 1. IC-705 +# 2. IC-7200 +SUBSYSTEM=="sound", ATTRS{idVendor}=="08bb", ATTRS{idProduct}=="2901", ENV{ET_DEVICE}=="", \ + ACTION=="add", \ + ATTR{id}="ET_AUDIO", \ + ENV{ET_DEVICE}="Icom generic", ENV{ET_SUBDEVICE}="AUDIO", GROUP="audio", MODE="0660", SYMLINK+="et-audio" diff --git a/overlay/etc/udev/rules.d/90-et-digirig-mobile.rules b/overlay/etc/udev/rules.d/90-et-digirig-mobile.rules index 7c35b11..74a26ca 100644 --- a/overlay/etc/udev/rules.d/90-et-digirig-mobile.rules +++ b/overlay/etc/udev/rules.d/90-et-digirig-mobile.rules @@ -1,25 +1,26 @@ # Author : Gaston Gonzalez # Date : 30 September 2024 -# Updated : 11 October 2024 +# Updated : 23 October 2024 # Purpose : udev rules for the DigiRig Mobile v1.9 # # Preconditions: -# 1. DigiRig Mobile connected via USB cable +# 1. DigiRig Mobile connected via USB cable # 2. This rule is processed after the IC-7200 # # Postconditions: # 1. /dev/et-cat created # 2. rigctld is started -# +# 3. /dev/et-audio created -# The IC-7200 uses the same chipsset. In order to avoid incorrect detection, we will check -# for the presence of ET_DEVICE as the IC-7200 will set it as an earlier rule. With this -# approach, the DigiRig Mobile rules must be processed later in the chain. SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", ENV{ET_DEVICE}=="", \ ACTION=="add", \ ENV{SYSTEMD_WANTS}="", \ ENV{ET_DEVICE}="DIGIRIG_MOBILE", ENV{ET_SUBDEVICE}="CAT", GROUP="dialout", MODE="0660", SYMLINK+="et-cat", \ RUN+="/usr/bin/systemctl start rigctld" +SUBSYSTEM=="sound", ATTRS{idVendor}=="0d8c", ATTRS{idProduct}=="013c", ENV{ET_DEVICE}=="", \ + ACTION=="add", \ + ATTR{id}="ET_AUDIO", \ + ENV{ET_DEVICE}="DIGIRIG_MOBILE", ENV{ET_SUBDEVICE}="AUDIO", GROUP="audio", MODE="0660", SYMLINK+="et-audio" + # TODO: Add rules for earlier 1.9 release -# TODO: Add rules for sound card diff --git a/overlay/etc/udev/rules.d/91-et-digirig-lite.rules b/overlay/etc/udev/rules.d/91-et-digirig-lite.rules new file mode 100644 index 0000000..75d61e5 --- /dev/null +++ b/overlay/etc/udev/rules.d/91-et-digirig-lite.rules @@ -0,0 +1,21 @@ +# Author : Gaston Gonzalez +# Date : 17 October 2024 +# Updated : 24 October 2024 +# Purpose : udev rules for the DigiRig Lite +# +# Preconditions: +# 1. The radio is set to 'generic-vox' using et-radio. +# 2. DigiRig Lite connected via USB cable +# +# Postconditions: +# 1. /dev/et-audio created +# 2. rigctld is started + +# The DigiRig Lite has no CAT control, but rigctld is started to minimize the configuration needed +# by the various amateur radio applications. EmComm Tools treats rigctl NET as its abstraction layer. +# A dummy rig control configuration is specifed in the 'generic-vox' radio configuration. +SUBSYSTEM=="sound", ATTRS{idVendor}=="0d8c", ATTRS{idProduct}=="0012", ENV{ET_DEVICE}=="", \ + ACTION=="add", \ + ATTR{id}="ET_AUDIO", \ + ENV{ET_DEVICE}="DIGIRIG_LITE", ENV{ET_SUBDEVICE}="AUDIO", GROUP="audio", MODE="0660", SYMLINK+="et-audio" \ + RUN+="/usr/bin/systemctl start rigctld" diff --git a/overlay/etc/udev/rules.d/91-et-u-blox.rules b/overlay/etc/udev/rules.d/92-et-u-blox.rules similarity index 100% rename from overlay/etc/udev/rules.d/91-et-u-blox.rules rename to overlay/etc/udev/rules.d/92-et-u-blox.rules diff --git a/overlay/lib/systemd/system/rigctld.service b/overlay/lib/systemd/system/rigctld.service index dd81b8a..2c1ba9d 100644 --- a/overlay/lib/systemd/system/rigctld.service +++ b/overlay/lib/systemd/system/rigctld.service @@ -1,6 +1,6 @@ [Unit] Description=Rig Control Service -ConditionPathExists=/dev/et-cat +#ConditionPathExists=/dev/et-cat After=multi-user.target [Service] diff --git a/overlay/opt/emcomm-tools/bin/et-js8call b/overlay/opt/emcomm-tools/bin/et-js8call new file mode 100755 index 0000000..c784270 --- /dev/null +++ b/overlay/opt/emcomm-tools/bin/et-js8call @@ -0,0 +1,82 @@ +#!/bin/bash +# +# Author : Gaston Gonzalez +# Date : 24 October 2024 +# Purpose : Wrapper script for starting JS8Call with PnP support +# +# Preconditions +# 1. Support radio and audio interface are connected and properly detected +# +# Postconditions +# 1. JS8Call is started with audio settings updated + +usage() { + echo "usage: $(basename $0) " + echo " start - Update config and start JS8Call" + echo " update-config - Update config" +} + +if [ $# -ne 1 ]; then + usage + exit 1 +fi + +start() { + update-config && /usr/bin/js8call & +} + +update-config () { + + JS8CALL_CONF_FILE="${HOME}/.config/JS8Call.ini" + + # 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 + AUDIO_DEVICE=$(echo $APLAY_OUT | cut -d"," -f2 | cut -d":" -f1 | awk '{print $2}') + JS8_AUDIO_DEVICE="plughw:CARD=ET_AUDIO,DEV=${AUDIO_DEVICE}" + et-log "Using '${JS8_AUDIO_DEVICE}' for JS8Call configuration." + + # 3. Check for existing JS8Call sound configuration + + ## Update input + grep "^SoundInName" ${JS8CALL_CONF_FILE} + if [ $? -eq 0 ]; then + sed -i "s|^SoundInName.*|SoundInName=\"${JS8_AUDIO_DEVICE}\"|" ${JS8CALL_CONF_FILE} + else + echo "SoundInName=\"${JS8_AUDIO_DEVICE}\"" >> ${JS8CALL_CONF_FILE} + fi + + ## Update output + grep "^SoundOutName" ${JS8CALL_CONF_FILE} + if [ $? -eq 0 ]; then + sed -i "s|^SoundOutName.*|SoundOutName=\"${JS8_AUDIO_DEVICE}\"|" ${JS8CALL_CONF_FILE} + else + echo "SoundOutName=\"${JS8_AUDIO_DEVICE}\"" >> ${JS8CALL_CONF_FILE} + fi + + else + et-log "No ET_AUDIO device detected." + exit 1 + fi + else + et-log "No ET_AUDIO device plugged in." + exit 1 + fi +} + +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-radio b/overlay/opt/emcomm-tools/bin/et-radio index 6b03977..e8e10d1 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 : 16 October 2024 +# Updated : 24 October 2024 # Purpose : A script for managaing plug-and-play radios set -e @@ -36,7 +36,10 @@ case $1 in ;; set) + NO_RADIO_ID="no-radio" + options=() + options+=("${NO_RADIO_ID}" "No radio") while IFS= read -r radio; do ID=$(cat $radio | jq -r .id) VENDOR=$(cat $radio | jq -r .vendor) @@ -45,17 +48,25 @@ case $1 in options+=("$ID" "$VENDOR $MODEL") done < <(find $ET_HOME/conf/radios.d -type f | sort) - selected_radio=$(dialog --clear --menu "Select a radio:" 15 50 10 "${options[@]}" 3>&1 1>&2 2>&3) + SELECTED_RADIO=$(dialog --clear --menu "Select a radio:" 15 50 10 "${options[@]}" 3>&1 1>&2 2>&3) exit_status=$? # Reset terminal to its original state - clear && tput sgr0 + clear && tput sgr0 if [ $exit_status -eq 0 ]; then - RADIO_CONF="${ET_HOME}/conf/radios.d/$selected_radio.json" + + # Special case to run without a radio configured + if [ ${SELECTED_RADIO} == ${NO_RADIO_ID} ]; then + [ -e ${ACTIVE_RADIO} ] && rm ${ACTIVE_RADIO} + echo "Set active radio to: $SELECTED_RADIO" + exit 0 + fi + + RADIO_CONF="${ET_HOME}/conf/radios.d/$SELECTED_RADIO.json" [ -e ${ACTIVE_RADIO} ] && rm ${ACTIVE_RADIO} ln -s ${RADIO_CONF} ${ACTIVE_RADIO} - echo "Set active radio to: $selected_radio" + echo "Set active radio to: $SELECTED_RADIO" else echo "No radio selected." fi @@ -64,7 +75,7 @@ case $1 in active) if [ ! -L "${ACTIVE_RADIO}" ]; then - echo "No active radio defined. Run: '$(basename $0) set '" + echo "No active radio defined. Run: '$(basename $0) set'" exit 1 fi diff --git a/overlay/opt/emcomm-tools/bin/et-system-info b/overlay/opt/emcomm-tools/bin/et-system-info index 7109e34..329bc4e 100755 --- a/overlay/opt/emcomm-tools/bin/et-system-info +++ b/overlay/opt/emcomm-tools/bin/et-system-info @@ -2,16 +2,18 @@ # # Author : Gaston Gonzalez # Date : 6 October 2024 -# Updated : 20 October 2024 +# Updated : 23 October 2024 # Purpose : Utility script for dumping system information function usage() { echo "Usage: $(basename $0) " - echo " active-radio - Display model of active radio" - echo " et-cat - Is CAT control connected" - echo " et-gps - Is the GPS connected" - echo " ip - System IP address" - echo " release - EmComm Tools Release" + echo " active-radio - Display model of active radio" + 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-gps - Show state of GPS interface" + echo " ip - System IP address" + echo " release - EmComm Tools release" } if [ $# -ne 1 ]; then @@ -26,6 +28,56 @@ case $1 in else echo "No radio selected" fi + ;; + et-audio) + + # 1. Check if the symlink was created by the udev rules + if [ -e /dev/et-audio ]; then + + UDEV_OUT=$(udevadm info /dev/et-audio | grep ET_DEVICE) + if [ $? -eq 0 ]; then + + # Display friendly audio device name + ET_DEVICE=$(udevadm info /dev/et-audio | grep ET_DEVICE | cut -d"=" -f2) + case $ET_DEVICE in + "DIGIRIG_LITE") + echo "DigiRig Lite" + ;; + "DIGIRIG_MOBILE") + echo "DigiRig Mobile" + ;; + *) + echo $ET_DEVICE + ;; + esac + + else + echo "Connected" + fi + + else + echo "Not connected" + fi + + ;; + et-audio-card) + + # 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 + AUDIO_CARD=$(echo $APLAY_OUT | cut -d":" -f1 | awk '{print $2}') + AUDIO_DEVICE=$(echo $APLAY_OUT | cut -d"," -f2 | cut -d":" -f1 | awk '{print $2}') + echo $AUDIO_CARD,$AUDIO_DEVICE + else + exit 1 + fi + else + exit 1 + fi + ;; et-cat) diff --git a/overlay/opt/emcomm-tools/conf/radios.d/generic-vox.json b/overlay/opt/emcomm-tools/conf/radios.d/generic-vox.json new file mode 100644 index 0000000..6869810 --- /dev/null +++ b/overlay/opt/emcomm-tools/conf/radios.d/generic-vox.json @@ -0,0 +1,11 @@ +{ + "id": "generic-vox", + "vendor": "Generic", + "model": "VOX", + "rigctrl": { + "id": "1", + "ptt": "NONE" + }, + "notes": [ + ] +} diff --git a/overlay/opt/emcomm-tools/sbin/wrapper-rigctld.sh b/overlay/opt/emcomm-tools/sbin/wrapper-rigctld.sh index 50eea1b..d403f48 100755 --- a/overlay/opt/emcomm-tools/sbin/wrapper-rigctld.sh +++ b/overlay/opt/emcomm-tools/sbin/wrapper-rigctld.sh @@ -2,6 +2,7 @@ # # Author : Gaston Gonzalez # Date : 9 October 2024 +# Updated : 24 October 2024 # Purpose : Wrapper startup/shutdown script around systemd/rigctld ET_HOME=/opt/emcomm-tools @@ -27,6 +28,24 @@ do_full_auto() { } start() { + + # Special case for VOX devices like the DigiRig Lite. + if [ -L "${ET_HOME}/conf/radios.d/active-radio.json" ]; then + CUR_RADIO=$(cat "${ET_HOME}/conf/radios.d/active-radio.json" | jq -r .model) + if [ "${CUR_RADIO}" = "VOX" ]; then + et-log "Starting dummy rigctld service for VOX device." + + ID=$(cat ${ET_HOME}/conf/radios.d/active-radio.json | jq -r .rigctrl.id) + PTT=$(cat ${ET_HOME}/conf/radios.d/active-radio.json | jq -r .rigctrl.ptt) + + CMD="rigctld -m ${ID} -P ${PTT} " + et-log "Starting rigctld with: ${CMD}" + $CMD + + exit 0 + fi + fi + if [ ! -e ${CAT_DEVICE} ]; then et-log "No CAT device found. ${CAT_DEVICE} symlink is missing." exit 1 @@ -58,7 +77,7 @@ start() { } stop() { - et-log "Stopping rigctld service..." + et-log "Stopping rigctld service..." systemctl stop rigctld if [ -L /dev/et-cat ]; then diff --git a/overlay/usr/share/applications/js8call.desktop b/overlay/usr/share/applications/js8call.desktop new file mode 100644 index 0000000..476608a --- /dev/null +++ b/overlay/usr/share/applications/js8call.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Version=1.0 +Name=js8call +Comment=Amateur Radio Weak Signal Operating +Exec=/opt/emcomm-tools/bin/et-js8call start +Icon=js8call_icon +Terminal=false +X-MultipleArgs=false +Type=Application +Categories=AudioVideo;Audio;HamRadio; +StartupNotify=true diff --git a/scripts/install-js8call.sh b/scripts/install-js8call.sh index d45f4b1..9bda5b1 100755 --- a/scripts/install-js8call.sh +++ b/scripts/install-js8call.sh @@ -1,7 +1,7 @@ #!/bin/bash # Author : Gaston Gonzalez # Date : 6 April 2023 -# Updated : 19 May 2024 +# Updated : 24 October 2024 # Purpose : Install JS8Call set -e trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG @@ -52,3 +52,6 @@ else fi dpkg -i $ET_DIST_DIR/$FILE + +et-log "Updating JS8Call launcher icon to support PNP..." +cp -v ../overlay/usr/share/applications/js8call.desktop /usr/share/applications/