#!/bin/bash
#
# Build script for UHD+GnuRadio on Fedora and Ubuntu
#
CWD=`pwd`
SUDOASKED=n
SYSTYPE=unknown
if [ -f /etc/fedora-release -o -f /etc/lsb-release ]
then
	good_to_go=yes
else
	echo You appear to not be running on a Fedora or Ubuntu system.
	echo This script will only run correctly on a Fedora or Ubuntu system.
	echo Exiting.
	exit
fi

echo This script will install Gnu Radio from current GIT sources
echo You will require Internet access from the computer on which this
echo script runs.  You will also require SUDO access.  You will require
echo approximately 500MB of free disk space to perform the build.
echo " "
echo This script will, as a side-effect, remove any existing Gnu Radio
echo installation that was installed from your Linux distribution packages.
echo It must do this to prevent problems due to interference between
echo a linux-distribution-installed Gnu Radio/UHD and one installed from GIT source.
echo " "
echo The whole process may take up to two hours to complete, depending on the
echo capabilities of your system.
echo -n Proceed?

read ans
case $ans in
	y|yes|Y|YES|Yes)
		PROCEED=y
	;;
	*)
		exit
esac

SPACE=`df $HOME| grep -v blocks|grep '%'`
SPACE=`echo $SPACE | awk '/./ {n=NF-2; printf ("%d\n", $n/1.0e3)}'`

if [ $SPACE -lt 500 ]
then
	echo "You don't appear to have enough free disk space on $HOME"
	echo to complete this build/install
	echo exiting
	exit
fi

function checkcmd {
	which $1 >tmp$$ 2>&1
	if grep -q no.${1}.in tmp$$
	then
		echo Failed to find command \'$1\' after pre-requisite installation.
		echo This very likely indicates that one or more parts of the
		echo pre-requisite installation has failed.
		rm -f tmp$$
		echo -n Show pre-requisites install log?
		read ans
		case $ans in
			y|Y|Yes|yes|YES)
				more prereq.log
			;;
		esac
		rm -f prereq.log
		rm -f tmp$$
		echo exiting build
		exit
	fi
	rm -f tmp$$
}

function checklib {
	found=0
	for dir in /lib /usr/lib /usr/lib64 /lib64
	do
		ls -l $dir/${1}*.so* >tmp$$ 2>&1
		if grep -q "No such" tmp$$
		then
			found=0
		else
			found=1
			if [ $2 -gt 0 ]
			then
				NL=`cat tmp$$|wc -l`
				if [ $NL -lt $2 ]
				then
					found=0
				fi
			fi
			break
		fi
		rm -f tmp$$
	done
	if [ $found -le 0 ]
	then
		echo Failed to find libraries with prefix \'$1\' after pre-requisite installation.
		echo This very likely indicates that the pre-requisite installation failed
		echo to install one or more critical pre-requisites for Gnu Radio/UHD
		echo -n Show pre-requisites install log?
		read ans
		case $ans in
			y|Y|yes|Yes|YES)
				more prereq.log
			;;
		esac
		rm -rf prereq.log
		echo exiting build
		exit
	fi
}

function checkpkg {
	echo Checking for package $1
	if [ `apt-cache search $1 | wc -l` -eq 0 ]
	then
		echo Failed to find package \'$1\' in known packages
		echo Perhaps you need to add the Ubuntu universe or multiverse PPA?
		echo see https://help.ubuntu.com/community/Repositories/Ubuntu
		rm -rf prereq.log
		echo exiting build
		exit
	fi
}
		
function prereqs {
	sudocheck
	echo -n Installing pre-prequisites...
	#
	# Check whether we're on a Fedora or Ubuntu system, and "do the right thing"
	#  for either system
	#
	# It's a Fedora system
	#
	if [ -f /etc/fedora-release ]
	then
		SYSTYPE=Fedora
		case `cat /etc/fedora-release` in
		*12*|*13*|*14*|*15*)
			sudo yum -y erase 'gnuradio*' >/dev/null 2>&1
			sudo yum -y erase 'libgruel-*' >/dev/null 2>&1
			sudo yum -y erase 'libgruel*' >/dev/null 2>&1
			sudo yum -y groupinstall "Engineering and Scientific" "Development Tools" >/dev/null 2>&1
			sudo yum -y install fftw-devel cppunit-devel wxPython-devel libusb-devel \
			  guile boost-devel alsa-lib-devel numpy gsl-devel python-devel pygsl \
			  python-cheetah python-lxml guile-devel PyOpenGL qt-devel qt qt4 qt4-devel \
			  PyQt4-devel qwt-devel qwtplot3d-qt4-devel libusb libusb-devel \
			  libusb1 libusb1-devel cmake git wget sdcc >prereq.log 2>&1
		;;
		*)
			echo Your Fedora system release must be at least release 12 to proceed
			exit
			;;
		esac
		
	#
	# It's a Ubuntu system
	#
	elif [ -f /etc/lsb-release ]
	then
		SYSTYPE=Ubuntu
		sudo apt-get purge 'gnuradio-*' >/dev/null 2>&1
		sudo apt-get purge 'libgruel-*' >/dev/null 2>&1
		sudo apt-get purge 'libgruel*' >/dev/null 2>&1
		sudo apt-get purge 'libgruel0*' >/dev/null 2>&1
		sudo apt-get purge 'libgnuradio*' >/dev/null 2>&1
		sudo apt-get purge 'python-gnuradio*' >/dev/null 2>&1
		case `grep DISTRIB_RELEASE /etc/lsb-release` in
		*11.*)
			PKGLIST="libfontconfig1-dev libxrender-dev libpulse-dev swig g++
			automake autoconf libtool python-dev libfftw3-dev
			libcppunit-dev libboost-all-dev libusb-dev libusb-1.0-0-dev fort77 sdcc sdcc-libraries
			libsdl1.2-dev python-wxgtk2.8 git-core guile-1.8-dev
			libqt4-dev python-numpy ccache python-opengl libgsl0-dev
			python-cheetah python-lxml doxygen qt4-dev-tools libusb-1.0-0-dev
			libqwt5-qt4-dev libqwtplot3d-qt4-dev pyqt4-dev-tools python-qwt5-qt4
			cmake git-core wget sdcc libxi-dev"
			;;
			
		*10.04*|*10.10*)
			PKGLIST="libfontconfig1-dev libxrender-dev libpulse-dev swig g++
			automake autoconf libtool python-dev libfftw3-dev
			libcppunit-dev libboost-all-dev libusb-dev libusb-1.0-0-dev fort77 sdcc sdcc-libraries
			libsdl1.2-dev python-wxgtk2.8 git-core guile-1.8-dev
			libqt4-dev python-numpy ccache python-opengl libgsl0-dev
			python-cheetah python-lxml doxygen qt4-dev-tools libusb-1.0-0-dev
			libqwt5-qt4-dev libqwtplot3d-qt4-dev pyqt4-dev-tools python-qwt5-qt4
			cmake git-core wget sdcc"
			;;
			
		*9.10*)
			PKGLIST="swig g++ automake autoconf libtool python-dev libfftw3-dev
			libcppunit-dev libboost1.38-dev libusb-dev libusb-1.0-0-dev fort77 sdcc sdcc-libraries
			libsdl1.2-dev python-wxgtk2.8 git-core guile-1.8-dev
			libqt4-dev python-numpy ccache python-opengl libgsl0-dev
			python-cheetah python-lxml doxygen qt4-dev-tools libusb-1.0-0-dev
			libqwt5-qt4-dev libqwtplot3d-qt4-dev pyqt4-dev-tools
			cmake git wget sdcc"
			;;
			
		*9.04*)
			sudo apt-get purge python-wxgtk2.6
			PKGLIST="swig g++ automake1.9 autoconf libtool python-dev fftw3-dev 
			libcppunit-dev libboost1.35-dev sdcc-nf libusb-dev libusb-1.0-0-dev 
			libsdl1.2-dev python-wxgtk2.8 git-core guile-1.8-dev 
			libqt4-dev python-numpy ccache python-opengl libgsl0-dev 
			python-cheetah python-lxml doxygen qt4-dev-tools 
			libqwt5-qt4-dev libqwtplot3d-qt4-dev pyqt4-dev-tools 
			cmake git wget"
			;;

			
		*)
			echo Your Ubuntu release must be at least 9.04 to proceed
			exit
			;;
		esac
		for pkg in $PKGLIST; do checkpkg $pkg; done
		sudo apt-get -y install $PKGLIST >prereq.log 2>&1
	else
		echo This script supports only Ubuntu and Fedora systems
		echo Your Fedora system must be at least Fedora 12
		echo Your Ubuntu system must be at least Ubuntu 9.04
		exit
	fi
	PATH=$PATH:/usr/libexec/sdcc
	export PATH
	
	checkcmd sdcc
	checkcmd guile
	checkcmd git
	checkcmd cmake
	
	if [ $SYSTYPE = Fedora ]
	then
		checklib libusb-0 0
		checklib libusb-1 0
	else
		checklib libusb 2
	fi
	
	checklib libboost_ 5
	checklib libcppunit 0
	checklib libguile 5
	checklib libfftw 5
	checklib libgsl 0
	
	rm -f prereq.log

	echo Done
}


function gitfetch {
	date=`date +%Y%m%d%H%M%S`

	#
	# Check for existing gnuradio directory
	#
	if [ -d gnuradio ]
	then
		mv gnuradio gnuradio.$date
	fi

	#
	# Check for existing UHD directory
	#
	if [ -d uhd ]
	then
		mv uhd uhd.$date
	fi

	#
	# GIT the gnu radio source tree
	#
	echo -n Fetching Gnu Radio via GIT...
	git clone http://gnuradio.org/git/gnuradio.git >/dev/null 2>&1

	if [ ! -d gnuradio/gnuradio-core ]
	then
		echo GIT checkout of Gnu Radio failed!
		exit
	fi
	echo Done

	#
	# GIT the UHD source tree
	#
	echo -n Fetching UHD via GIT...
	git clone git://code.ettus.com/ettus/uhd.git >/dev/null 2>&1

	if [ ! -d uhd/host ]
	then
		echo GIT checkout of UHD failed!
		exit
	fi
	echo Done
}

function uhd_build {
	#
	# UHD build
	#
	sudocheck
	if [ ! -d uhd ]
	then
		echo you do not appear to have the \'uhd\' directory
		echo you should probably use $0 gitfetch to fetch the appropriate
		echo files using GIT
		exit
	fi
	echo -n Building UHD...
	cd uhd/host
	if [ ! -d build ]
	then
		mkdir build
	fi
	cd build
	cmake ../ >cmake.log 2>&1
	make clean >/dev/null 2>&1
	make >make.log 2>&1
	if [ $? -ne 0 ]
	then
		echo make of UHD failed
		echo -n View log?
		read ans
		case $ans in
			y|Y|yes|YES|Yes)
				more make.log
				;;
		esac
		echo Exiting UHD build
		exit
	fi
	sudo make install >UHD_install.log 2>&1
	sudo chmod 644 UHD_install.log
	if [ ! -f /usr/local/bin/uhd_find_devices ]
	then
		echo UHD build/install apparently failed
		echo -n View UHD install 'log?'
		read ans
		case $ans in
			y|Y|yes|YES|Yes)
				more UHD_install.log
				;;
		esac
		echo Exiting UHD build
		exit
	fi
	sudo ldconfig
	echo Done building/installing UHD
}

function firmware {
	sudocheck
	#
	# Firmware/FPGA images...
	#
	echo Fetching and installing FPGA/Firmware images via wget...
	
	#
	# First, get listing of ettus.com/downloads/uhd_releases
	# We use spider mode, and use -r to descend
	#
	wget -np -r --spider http://www.ettus.com/downloads/uhd_releases >tmp$$ 2>&1
	
	#
	# Now search the resulting log file for .tar.gz files that match the appropriate
	#   pattern.
	#
	grep '.--.*http.*images-only.*tar.gz' tmp$$ |sed -e 's/.*http:/http:/' |sort -r |head -1 >tmp2$$
	
	#
	# tmp2$$ should now contain only the most numerically-recent instance of the
	#  appropriate TAR file
	#
	rm -f tmp$$
	rm -rf wget-tmp*
	
	#
	# Make a temporary directory to unpark the TAR file into and go there
	#
	mkdir wget-tmp$$
	cd wget-tmp$$
	
	#
	# Fetch the tar file (whose name is in ../tmp2$$)
	#
	wget -nd `cat ../tmp2$$`  >/dev/null 2>&1
	
	#
	# Pick out only the filename part of the URL
	#
	fn=`cat ../tmp2$$|sed -e 's/.*images-only.//'`
	rm -f ../tmp2$$
	
	#
	# Check to make sure we got it
	#
	if [ ! -f $fn ]
	then
		echo Failed to fetch $fn: with latest UHD firmware/fpga images
		exit
	fi
	
	#
	# Now unpack the tar file
	#
	echo ...Installing from: $fn
	tar xf $fn
	
	if [ ! -d UHD*/share/uhd/images ]
	then
		echo There was a problem with the TAR file: $fn
		echo The appropriate directories were not unpacked from it
		echo In particular, UHD.../share/uhd/images does not exist
		exit
	fi
	
	#
	# There's now a directory structure from the tar file
	# Descend into it and copy the images to /usr/local/share/uhd/images
	#
	cd UHD*/share/uhd/images
	if [ ! -d /usr/local/share/uhd/images ]
	then
		sudo mkdir -p /usr/local/share/uhd/images
	fi
	echo ...Copying into /usr/local/share/uhd
	sudo cp * /usr/local/share/uhd/images
	sudo chmod 644 /usr/local/share/uhd/images/*
	cd $CWD
	rm -rf wget-tmp$$
	echo Done
}

function gnuradio_build {
	sudocheck
	
	if [ ! -d gnuradio ]
	then
		echo you do not appear to have the \'gnuradio\' directory
		echo you should probably use $0 gitfetch to fetch the appropriate
		echo files using GIT
		exit
	fi
	
	#
	# LD stuff
	#
	echo /usr/local/lib >tmp$$
	echo /usr/local/lib64 >>tmp$$

	if grep -q /usr/local/lib /etc/ld.so.conf.d/*
	then
		echo /usr/local/lib already in ld.so.conf.d
	else
		sudo cp tmp$$ /etc/ld.so.conf.d/local.conf
	fi
	rm -f tmp$$
	echo Doing ldconfig...
	sudo ldconfig >/dev/null 2>&1

	PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
	export PKG_CONFIG_PATH

	#
	# Build Gnuradio
	#
	echo Building Gnu Radio...
	cd gnuradio
	echo .....Bootstrapping
	./bootstrap >/dev/null 2>&1
	echo .....Configuring
	./configure >/dev/null 2>&1
	echo .....Building
	make clean >/dev/null 2>&1
	make >make.log 2>&1
	if [ $? -ne 0 ]
	then
		echo make failed
		echo -n View log?
		read ans
		case $ans in
			y|Y|yes|YES)
				more make.log
				;;
		esac
		rm -f make.log
		echo Exiting Gnu Radio build/install
		exit
	fi
	rm -f make.log
	echo ....Installing
	sudo make install >/dev/null 2>&1
	sudo ldconfig
	echo Done building and installing Gnu Radio
	if [ -f /usr/local/libexec/gnuradio/grc_setup_freedesktop ]
	then
		sudo /usr/local/libexec/gnuradio/grc_setup_freedesktop install
	fi
}

function mod_groups {
	sudocheck
	#
	# Post install stuff
	#
	# USRP rules for UDEV and USRP group
	#
	#
	# Check for USRP group, and update if necessary
	if grep -q usrp /etc/group
	then
		echo Group \'usrp\' already in /etc/group
	else
		sudo /usr/sbin/groupadd usrp
	fi

	#
	# Check that our calling user is in the USRP group, update if necessary
	#
	if grep -q usrp.*${USER} /etc/group
	then
		echo User $USER already in group \'usrp\'
	else
		sudo /usr/sbin/usermod -a -G usrp $USER
cat <<"!EOF!"
********************************************************************************
This script has just modified /etc/group to place your userid into group 'usrp'
In order for this change to take effect, you will need to log-out and log back
in again.  You will not be able to access your USRP1 device until you do this.
********************************************************************************
!EOF!

	fi
}

function mod_udev {
	sudocheck
	#
	# Check for UDEV rules file, update if necessary
	#
	if [ ! -f /etc/udev/rules.d/10-usrp.rules ]
	then
		cat >>tmp$$ <<"!EOF!"
# rule to grant read/write access on USRP to group named usrp.
# to use, install this file in /etc/udev/rules.d as 10-usrp.rules
ACTION=="add", BUS=="usb", SYSFS{idVendor}=="fffe", SYSFS{idProduct}=="0002", GROUP:="usrp", MODE:="0660"
!EOF!
		chmod 644 tmp$$
		sudo mv tmp$$ /etc/udev/rules.d/10-usrp.rules
		sudo killall -HUP udevd
		sudo udevadm control --reload-rules
		rm -f tmp$$
	else
		echo USRP rules for UDEV already in place
	fi
}

function mod_sysctl {
	sudocheck
	#
	# Modify sysctl.conf as necessary
	#
	cat >tmp$$ <<!EOF!
# Updates for Gnu Radio
net.core.rmem_max = 1000000
net.core.wmem_max = 1000000
kernel.shmmax = 2147483648
!EOF!


	if grep -q 'Updates for Gnu Radio' /etc/sysctl.conf
	then
		echo Required updates to /etc/sysctl.conf already in place
	else
		echo Applying updates to /etc/sysctl.conf
		cat /etc/sysctl.conf tmp$$ >tmp2$$
		chmod 644 tmp2$$
		sudo mv tmp2$$ /etc/sysctl.conf
	fi

	sudo sysctl -w net.core.rmem_max=1000000 >/dev/null 2>&1
	sudo sysctl -w net.core.wmem_max=1000000 >/dev/null 2>&1
	sudo sysctl -w kernel.shmmax=2147483648  >/dev/null 2>&1
	 
	rm -f tmp$$
	rm -f tmp2$$
	
	if grep -q usrp /etc/security/limits.conf
	then
		echo usrp group already has real-time scheduling privilege
	else
		echo "@usrp  - rtprio 50" >tmp$$
		cat /etc/security/limits.conf tmp$$ >tmp2$$
		sudo cp tmp2$$ /etc/security/limits.conf
		sudo chmod 644 /etc/security/limits.conf
		rm -f tmp$$ tmp2$$
		echo Group \'usrp\' now has real-time scheduling privileges
		echo You will need to log-out and back in again for this to
		echo take effect
	fi
}

function all {
	cd $CWD
	prereqs
	touch -d "2 hours ago" touch$$
	if [ -d uhd -a -d gnuradio ]
	then
		if [ uhd -ot touch$$ -o gnuradio -ot touch$$ ]
		then
			gitfetch
		else
			echo Skipping git fetch, since \'uhd\' and \'gnuradio\' are new enough
		fi
	else
		gitfetch
	fi
	rm -f touch$$
	for fcn in uhd_build firmware gnuradio_build mod_groups mod_udev mod_sysctl
	do
		cd $CWD
		$fcn
	done
}

function help {
	echo available functions are: all prereqs gitfetch uhd_build firmware gnuradio_build mod_groups mod_udev mod_sysctl
}

PATH=$PATH:/usr/libexec/sdcc
export PATH

function sudocheck {
	#
	# Check SUDO privileges
	#
	if [ $SUDOASKED = n ]
	then
		echo SUDO privileges are required 
		echo -n Do you have SUDO privileges'?'
		read ans
		case $ans in
			y|yes|YES|Y)
				echo Continuing with script
				SUDOASKED=y
				;;
			*)
				echo Exiting.  Please ensure that you have SUDO privileges on this system!
				exit
				;;
		esac
	fi
}

case $# in
	0)
		all
		exit
esac

for arg in $*
do
	cd $CWD
	$arg
done
