#!/bin/bash

# Part of the HamPacket documentation found at
# http://www.trinityos.com/HAM/index-ham.html

#03/04/18
#dranch@trinnet.net

#03/10/18 - Disabled Fldigi check
#
#03/04/18 - added key -echo statement to stty initialization; fixes to variable 
#           names, added more clarifying comments to the script
#
#02/15/15 - Fixed serious typos in using /r instead of the correct \r
#         - Re-arrange routines and improved troubleshooting steps
#
#04/09/12 - Support reading / writing configs, supports command line options
#
#06/04/11 - Added a kill kmix as the KDE mixer keeps popping up after
#           running this script
#
#07/24/10 - orig version


# NOTES:
#
# 1. This script is used to reset the US Interface Navigator unit if the # ALSA or USB 
#    enumeration changes
#
# 2. You send "UPPERCASE" letter commands and the Navigator will respond with the same command
#    "lowercase" and any additional response
#
# 3. You cannot interact with the Navigator using Minicom unless "Add linefeed" is 
#    set to NO but even then, it doesn't seem to be reliable.  Commands have to be sent
#    multiple times.  Using "cat" statements seems reliable


#Variables
#----------

# You have enabled Udev support for your navigator to support deterministic serial port naming.  You
#  and also put in names like "/dev/ttyUSB4" if you wish
#
#  NOTE:  Due to a bug in the script, if you use a different device name here, you'll 
#         need to edit this script and change the device name elsewhere as well
#      
USIPORT="/dev/USI_CFG"

#What the ALSA sound enumeration should look like for my laptop here
#
#[root@hampacket dranch]# cat /proc/asound/cards
# 0 [I82801DBICH4   ]: ICH4 - Intel 82801DB-ICH4
#                      Intel 82801DB-ICH4 with STAC9750,51 at irq 7
# 1 [Modem          ]: ICH-MODEM - Intel 82801DB-ICH4 Modem
#                      Intel 82801DB-ICH4 Modem at irq 7
# 2 [default        ]: USB-Audio - USB Audio CODEC
#                      Burr-Brown from TI              USB Audio CODEC  at usb-0

#Where to find modprobe
MODPROBE="/sbin/modprobe"

#Xterm is used for monitoring the output from the Navigator
XTERM="/usr/bin/xterm"


# Functions
#----------

function USAGE {
   echo -e "\n\nUsage: "
   echo -e "us-navigator-command.sh <command>"
   echo -e " "
   echo -e "   command:"
   echo -e "           reset      - Linux USB kernel modules are reset"
   echo -e "           remove-snd - removes sound only, no USB reset"
   echo -e "           read-cfg   - Read the settings from the Navigator"
   echo -e "           write-cfg  - Write the settings from the Navigator"
   echo -e "\n\nexit\n\n"
   exit 0
}

function USI_INIT {
   echo -e "\nInitializing $USIPORT to 1200 baud :: Any speed shown here was the previous initialized port speed"
   #suppressing the echo here is key to keep the navigator from spinning into an endless loop
   stty -F $USIPORT speed 1200 -echo

   #initialize the CONFIG port - do it twice - Navigator will respond with lowecase "kt"
   echo -e "KT" > $USIPORT
   echo -e "KT" > $USIPORT

   sleep 1

   echo -e "\nDimming Navigator LEDs twice - if this doesn't work, please troubleshoot\n"
   #DIM the LEDs to show we're successfully writing to the device - Navigator will respond with lowercase "kl"
   #Dim the LEDs
   echo -e "KL11100111111" > $USIPORT
   sleep 0.5
   #Brighten the LEDs
   echo -e "KL11101111111" > $USIPORT
   sleep 0.5
   #Dim the LEDs
   echo -e "KL11100111111" > $USIPORT
   sleep 0.5
   #Brighten the LEDs
   echo -e "KL11101111111" > $USIPORT
}

function USI_MONITOR {
   #Improve this to do this inline and not use an xterm
   echo -e "Opening Xterm to display Navigator settings on $USIPORT"

   #Have to hard code in the port here as variable substitution isn't working right
   $XTERM -sb -geometry 100x24 -T "usinterface-commands.sh output" -e 'echo -e "\nCurrent configuration of the /dev/USI_CFG attached Navigator"; 
   echo -e "\nkm terminator shown below is REQUIRED.  Any incomplete response means the Navigator should be power cycled";
   echo -e "\nClose this window when done\n";
   echo "+------------0  CH.1 attenuator  - 0 for 15db attenuation or 1 for DEFAULT:no atten";
   echo "|+-----------1  CH.2 attenuator  - 0 for 15db attenuation or 1 for DEFAULT:no atten";
   echo "||+----------2  RF attenuator    - 0 for 20db attenuation or 1 for DEFAULT:no atten";
   echo "|||+---------3  WinKey PTT       - 0 for DEFAULT:NO PTT   or 1 for WinKey PTT";
   echo "||||+--------4  LED brightness   - 0 for Dim brightness   or 1 for DEFAULT:normal brightness";
   echo "|||||+-------5  CAT LED behavior - 0 for steady led       or 1 for DEFAULT:on-access poll";
   echo "||||||+------6  FSK polarity     - 0 for reverse          or 1 for DEFAULT:normal polarity";
   echo "|||||||+-----7  FSK side tone    - 0 for no tone          or 1 for DEFAULT:tone";
   echo "||||||||+----8  FSK PTT          - 0 for PTT disabled     or 1 for DEFAULT:PTT enabled";
   echo "|||||||||+---9  FSK BAUD rate    - 1 for DEFAULT:45.45    or 2 for 75       or 3 for 100 baud";
   echo "||||||||||+-10  FSK stop bits    - 1 for DEFAULT:1 bit    or 2 for 1.5 bits or 3 for 2 bits";
   echo "|||||||||||"; cat /dev/USI_CFG' &
   #   km11101111111   -- example EEPROM read result

   #An alternative way but needs to forked into the background
   #while read line; do
   #   if [ "$line" != "kt" ]; then
   #      echo "$line"
   #     else
   #      break 
   #   fi
   #done < /dev/USI_CFG

   sleep 1
   #killall cat
}

#Main program
#---------------------------------------------------------------------
if [ $UID -ne 0 ]; then
  echo -e "\nError: You must be root! Abort.\n"
  exit 1
fi

#031018 - disabled as I think this isn't correct
#if [ -n "`ps aux | grep -i fldigi | grep -v grep`" ]; then
#   echo -e "\ERROR: fldigi is running and will most likely conflict.  Abort.\n"
#   exit 1
#fi

if [ "$1" = "-h" ] || [ -z $1 ]; then
   USAGE
fi


# Read Config
# -----------
if [ "$1" == "read-cfg" ]; then

   #Initialize the Navigator
   USI_INIT

   USI_MONITOR

   #Good response should return a lowercase "kr" - won't be shown as the Xterm takes too long to 
   #  start - loosing this line actually makes the xterm output a little prettier
   #sleep 0.5

   echo -e "Restoring User specified settings from EEPROM"
   echo -e "KR" > $USIPORT
   sleep 0.5
   #Good response should return a lowercase "km"
   echo -e "\nDisplay loaded Navigator settings in Xterm"
   echo -e "KM" > $USIPORT
   sleep 0.5

   #echo -e "\nDisabled as there is a looping problem right now"
   #echo -e "You can use minicom to monitor but you must use echo statements"
   #echo -e "to send valid commands as it only wants LF and not CRLF"
   #cat $USIPORT
 
   echo " "
fi
   
if [ "$1" == "write-cfg" ]; then
  echo -e "\nWriting the USI Navigator configuration on: $USIPORT"
  #bit field	Description	Setting
  #0	CH.1 attenuator  "0" for 15db attenuation or "1" for DEFAULT:no attenuation
  #1	CH.2 attenuator  "0" for 15db attenuation or "1" for DEFAULT:no attenuation
  #2	RF attenuator    "0" for 20db attenuation or "1" for DEFAULT:no attenuation
  #3	WinKey PTT       "0" for DEFAULT:NO PTT   or "1" for WinKey PTT           <------------- Changed
  #4	LED brightness   "0" for DIM              or "1" for DEFAULT:normal brightness
  #5	CAT LED behavior "0" for steady           or "1" for DEFAULT:on-access polling
  #6	FSK polarity	 "0" for reverse          or "1" for DEFAULT:normal polarity
  #7	FSK side tone	 "0" for no tone          or "1" for DEFAULT:tone
  #8	FSK PTT	         "0" for PTT disabled     or "1" for DEFAULT:PTT enabled
  #9	FSK BAUD rate	 "1" for DEFAULT:45.45, "2" for 75, or "3" for 100 baud
  #10	FSK stop bits 	 "1" for DEFAULT:1 bit, "2" for 1.5 bits, or " 3" for 2 bits

  #Receive Config Set (KL) - PC sends Config Set to Nav
  #“KL” & Config Set & CRLF
  #Nav responds with the string: “kl” & NL
  #--
  #Send Config Set (KM) - Nav reads Config Set and sends it to the PC
  #“KM” & CRLF
  #Nav responds with the string: Config Set & “km” & NL
  #--
  #Send Version - Nav sends Config CPU firmware version number string
  #“KQ” & CRLF
  #Nav responds with the string: “Ver 1.00” & NL -
  #--
  #Restore Config Set - Nav resets the Config Set to the values in EEPROM
  #“KR” & CRLF
  #Nav responds with the string: “kr” & NL
  #--
  #Save Config Set to Default - Nav copies Config Set to EEPROM
  #“KS” & CRLF
  #Nav responds with the string: “ks” & NL
  #--
  #No Op No operation performed – used for synchronizing PC and Nav communication
  #“KT” & CRLF
  #Nav responds with the string: “kt” & NL
  #

   #Initialize the Navigator
   USI_INIT

   USI_MONITOR

   echo -e "Loading User specified EEPROM defaults"
   echo -e "KR" > $USIPORT
   sleep 0.5

   #Restore defaults - send twice as it doesn't always take first time
   #test string
   echo "Writing KI6ZHD specific settings TWICE"
   echo -e "KL11101111111" > $USIPORT
   sleep 0.5
   echo -e "KL11101111111" > $USIPORT
   sleep 0.5

   #echo "Reading contents of EEPROM"
   #echo -e "KM\r" > $USIPORT
   #sleep 0.5

   #Default string
   #echo -e "KL11101111111\r" > $USIPORT
   #echo -e "KL11101111111\r" > $USIPORT


   #If you'd like to save these settings as the default
   echo "Saving new settings to EEPROM TWICE"
   echo -e "KS" > $USIPORT
   sleep 0.5
   echo -e "KS" > $USIPORT
   sleep 0.5

   echo "Re-Reading contents of EEPROM"
   echo -e "KM" > $USIPORT
   sleep 0.5
fi


if [ "$1" == "reset" ] || [ "$1" == "remove-snd" ]; then
  echo -e "Resetting the USB system"

  REMOVE_STAGE1="ftdi_sio snd_usb_audio snd_intel8x0m snd_intel8x0"
  ADD_STAGE1="ehci_hcd ohci_hcd uhci_hcd"

  REMOVE_STAGE2="uhci_hcd ohci_hcd ehci_hcd"
  ADD_STAGE2="snd_intel8x0 snd_intel8x0m snd_usb_audio ftdi_sio"

  echo -e "\nDisabling stage1:"
  for I in $REMOVE_STAGE1; do
     echo -en "   [$I] "
     $MODPROBE -r $I
  done

  if [ "$1" = "remove-snd" ]; then
     echo -e "\n\n   Remove USB sound only.  Done.\n\n"
     exit 0
  fi

  echo -e "\nDisabling stage2:"
  for I in $REMOVE_STAGE2; do
     echo -en "   [$I] "
     $MODPROBE -r $I
  done

  #Ok, let's reload things

  echo -e "\n\nEnabling stage1:"
  for I in $ADD_STAGE1; do
     echo -en "   [$I] "
     $MODPROBE $I
  done

  echo -e "\nEnabling stage2:"
  for I in $ADD_STAGE2; do
     echo -en "   [$I] "
     $MODPROBE $I
  done

  echo -e "\n"
  /usr/local/bin/usinterface-ident.orig.sh
fi


echo -e "\ndone\n\n"
