#!/bin/bash
################################################################################
#   OpenAirInterface
#   Copyright(c) 1999 - 2014 Eurecom
#
#    OpenAirInterface is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) anylater version.
#
#
#    OpenAirInterface is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with OpenAirInterface.The full GNU General Public License is
#    included in this distribution in the file called "COPYING". If not,
#    see <http://www.gnu.org/licenses/>.
#
#  Contact Information
#  OpenAirInterface Admin: openair_admin@eurecom.fr
#  OpenAirInterface Tech : openair_tech@eurecom.fr
#  OpenAirInterface Dev  : openair4g-devel@eurecom.fr
#
#  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
#
################################################################################
# file build_oai
# brief OAI automated build tool that can be used to install, compile, run OAI.
# author  Navid Nikaein, Lionel GAUTHIER, Laurent Thomas


################################
# include helper functions
################################
ORIGIN_PATH=$PWD
THIS_SCRIPT_PATH=$(dirname $(readlink -f $0))
source $THIS_SCRIPT_PATH/tools/build_helper

MSC_GEN="False"
XFORMS="False"
VCD_TIMING="False"
REL="Rel10"
HW="EXMIMO"
EPC=0

function print_help() {
  echo_info '
This program installs OpenAirInterface Software
You should have ubuntu 14.xx, updated, and the Linux kernel >= 3.14
Options
-h
   This help
-c | --clean
   Erase all files to make a rebuild from start"
-C | --clean-all
   Erase all files made by previous compilations, installations"
--clean-kernel
   Erase previously installed features in kernel: iptables, drivers, ...
-I | --install-external-packages
   Installs required packages such as LibXML, asn1.1 compiler, freediameter, ...
   This option will require root password
--install-optional-packages
   Install useful but not mandatory packages such as valgrind
-g | --run-with-gdb
   Add debugging symbols to compilation directives
-h | --help
   Print this help
--eNB
   Makes the LTE softmodem
--UE
   Makes the UE specific parts (ue_ip, usim, nvram) 
--EPC
   Makes the EPC (MME-SPGW, HSS)
-r | --3gpp-release
   default is Rel10,
   Rel8 limits the implementation to 3GPP Release 8 version
-w | --hardware
   EXMIMO (Default), USRP, BLADERF, None
   Adds this RF board support (in external packages installation and in compilation)
--oaisim
   Makes the oaisim simulator
--phy_simulators
   Makes the unitary tests Layer 1 simulators
--core_simulators
   Makes the core security features unitary simulators
-s | --check
   runs a set of auto-tests based on simulators and several compilation tests
-V | --vcd
   Adds a debgging facility to the binary files: GUI with major internal synchronization events
-x | --xforms
   Adds a software oscilloscope feature to the produced binaries
--install-system-files
   Install OpenArInterface required files in Linux system
   (will ask root password)
Typical Options for a quick startup with a COTS UE and Eurecom RF board: build_oai -I -g -eNB -EPC -x --install-system-files'
}


function main() {
  until [ -z "$1" ]
  do
    case "$1" in
       -c | --clean)
            CLEAN=1
            shift;;
       -C | --clean-all)
            CLEAN_ALL=1
            shift;;
       --clean-kernel)
            clean_kernel
            echo_info "Erased iptables config and removed modules from kernel"
            shift;;
       -I | --install-external-packages)
            INSTALL_EXTERNAL=1
            echo_info "Will install external packages"
            shift;;
       --install-optional-packages)
            INSTALL_OPTIONAL=1
            echo_info "Will install optional packages"
            shift;;
       -g | --run-with-gdb)
            GDB=1
            echo_info "Will Compile with gdb symbols"
            shift;;
       --eNB)
            eNB=1
            echo_info "Will compile eNB"
            shift;;
       --UE)
            UE=1
            echo_info "Will compile UE"
            shift;;
       --EPC)
            EPC=1
            echo_info "Will compile EPC"
            shift;;
       -r | --3gpp-release)
            REL=$2
            echo_info "setting release to: $REL"
            shift 2;;
       -w | --hardware)
            HW="$2" #"${i#*=}"
            # Use OAI_USRP  as the key word USRP is used inside UHD driver
            if [ "$HW" == "USRP" ] ; then 
		HW="OAI_USRP"
	    fi 
            if [ "$HW" == "BLADERF" ] ; then 
		HW="OAI_BLADERF"
	    fi 
            echo_info "setting hardware to: $HW"
            shift 2;;
       --oaisim)
            oaisim=1
            echo_info "Will compile oaisim and drivers nasmesh, ..."
            shift;;
       --phy_simulators)
            SIMUS_PHY=1
            echo_info "Will compile dlsim, ulsim, ..."
            shift;;
       --core_simulators)
            SIMUS_CORE=1
            echo_info "Will compile security unitary tests"
            shift;;
       -s | --check)
            OAI_TEST=1
            echo_info "Will run auto-tests"
            shift;;
       -V | --vcd)
            echo_info "setting gtk-wave output"
            VCD_TIMING=1
            EXE_ARGUMENTS="$EXE_ARGUMENTS -V"
            shift;;
       -x | --xforms)
            XFORMS=1
            EXE_ARGUMENTS="$EXE_ARGUMENTS -d"
            echo_info "Will generate the software oscilloscope features"
            shift;;
       --install-system-files)
            INSTALL_SYSTEM_FILES=1
            echo_info "Will copy OpenAirInterface files in Linux directories"
            shift;;
        -h | --help)
            print_help
            exit 1;;
	*)
	    print_help
            echo_fatal "Unknown option $1"
            break;;
   esac
  done

  ############################################
  # setting and printing OAI envs, we should check here
  ############################################

  echo_info "2. Setting the OAI PATHS ..."

  set_openair_env
  cecho "OPENAIR_DIR    = $OPENAIR_DIR" $green

  # for conf files copy in this bash script
  if [ -d /usr/lib/freeDiameter ]; then
    export FREEDIAMETER_PREFIX=/usr
  else
    if [ -d /usr/local/lib/freeDiameter ]; then
      export FREEDIAMETER_PREFIX=/usr/local
    else
      echo_warning "FreeDiameter prefix not found, install freeDiameter if EPC, HSS"
    fi
  fi


  if [ "$CLEAN_ALL" = "1" ] ; then
    clean_all_files
    echo_info "Erased all previously producted files"
  fi

  dbin=$OPENAIR_DIR/targets/bin
  dlog=$OPENAIR_DIR/cmake_targets/log
  mkdir -p $dbin $dlog

  if [ "$INSTALL_EXTERNAL" = "1" ] ; then
    echo_info "Installing packages"
    check_install_oai_software
    echo_info "Making X.509 certificates"
    make_certs eur
    if [ "$HW" == "OAI_USRP" ] ; then
      echo_info "installing packages for USRP support"
      check_install_usrp_uhd_driver
    fi
    if [ "$HW" == "OAI_BLADERF" ] ; then
      echo_info "installing packages for BALDERF support"
      check_install_bladerf_driver
    fi

  fi

  if [ "$INSTALL_OPTIONAL" = "1" ] ; then
    echo_info "Installing optional packages"
    check_install_additional_tools
  fi

  echo_info "3. building the compilation directives ..."

  DIR=$OPENAIR_DIR/cmake_targets


  if [ "$eNB" = "1" -o "$UE" = "1" ] ; then
    # LTE softmodem compilation
    [ "$CLEAN" = "1" ] && rm -rf $DIR/lte_build_oai/build
    mkdir -p $DIR/lte_build_oai/build
    cmake_file=$DIR/lte_build_oai/CMakeLists.txt
    echo "cmake_minimum_required(VERSION 2.8)"   >   $cmake_file
    echo "set(XFORMS $XFORMS )"                  >>  $cmake_file
    echo "set(RRC_ASN1_VERSION \"${REL}\")"      >>  $cmake_file
    echo "set(ENABLE_VCD_FIFO $VCD_TIMING )"     >>  $cmake_file
    echo "set(RF_BOARD \"${HW}\")"               >>  $cmake_file
    echo 'set(PACKAGE_NAME "\"lte-softmodem\"")' >>  $cmake_file
    echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
    cd  $DIR/lte_build_oai/build
    cmake ..
    echo_info "Compiling LTE softmodem"
    compilations \
	  lte_build_oai lte-softmodem \
	  lte-softmodem $dbin/lte-softmodem.$REL

    # LTE softmodem (no S1 interface) compilation
    [ "$CLEAN" = "1" ] && rm -rf $DIR/lte_noS1_build_oai/build
    mkdir -p $DIR/lte_noS1_build_oai/build
    cd  $DIR/lte_noS1_build_oai/build
    cmake ..
    echo_info "Compiling LTE softmodem (w/o S1 interface)"
    compilations \
	  lte_noS1_build_oai lte-softmodem \
	  lte-softmodem $dbin/lte-softmodem-nos1
    compilations \
	  lte_noS1_build_oai nasmesh \
	  CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko
    compilations \
	  lte_noS1_build_oai rb_tool \
	  rb_tool $dbin/rb_tool
    cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin
  fi

  if [ "$UE" = 1 ] ; then
    # ue_ip driver compilation
    echo_info "Compiling UE specific part"
    compilations \
      lte_build_oai ue_ip \
      CMakeFiles/ue_ip/ue_ip.ko $dbin/ue_ip.ko
      
#    mkdir -p $DIR/at_commands/build
#    cd $DIR/at_commands/build
#    cmake ..
#    compilations \
#      at_commands at_nas_ue \
#      at_nas_ue $dbin/at_nas_ue
      
    [ "$CLEAN" = "1" ] && rm -rf $DIR/nas_sim_tools/build
    mkdir -p $DIR/nas_sim_tools/build
    cd $DIR/nas_sim_tools/build
    
    cmake ..
    compilations \
      nas_sim_tools usim \
      usim $dbin/usim
    compilations \
      nas_sim_tools nvram \
      nvram $dbin/nvram

    # generate USIM data
    if [ -f $dbin/nvram ]; then
      install_nas_tools $dbin $dconf
    else
      echo_warning "not generated UE NAS files: binaries not found"
    fi
  fi

  if [ "$SIMUS_PHY" = "1" -o "$SIMUS_CORE" = "1" ] ; then
    cd $OPENAIR_DIR/cmake_targets/lte-simulators
    [ "$CLEAN" = "1" ] && rm -rf build
    mkdir -p build
    cd build
    rm -f *sim
    cmake ..
  fi

  if [ "$SIMUS_PHY" = "1" ] ; then
    # lte unitary simulators compilation
    echo_info "Compiling unitary tests simulators"
    simlist="dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim"
    for f in $simlist ; do
      compilations \
      lte-simulators $f \
	  $f $dbin/$f.$REL
    done
  fi

  # Core simulators
  #############
  if [ "$SIMUS_CORE" = "1" ] ; then
    # lte unitary simulators compilation
    echo_info "Compiling unitary tests simulators"
    simlist="secu_knas_encrypt_eia1 secu_kenb aes128_ctr_encrypt aes128_ctr_decrypt secu_knas_encrypt_eea2 secu_knas secu_knas_encrypt_eea1 kdf aes128_cmac_encrypt secu_knas_encrypt_eia2"
    for f in $simlist ; do
      compilations \
	  lte-simulators test_$f \
	  test_$f $dbin/test_$f.$REL
    done
  fi

  # EXMIMO drivers & firmware loader
  ###############
  if [ "$HW" = "EXMIMO" -a "$EPC" = "0" ] ; then
    
    echo_info "Compiling Express MIMO 2 board drivers"
    mkdir -p $DIR/lte_noS1_build_oai/build
    cd $DIR/lte_noS1_build_oai/build
    cmake ..
    compilations \
        lte_noS1_build_oai openair_rf \
        CMakeFiles/openair_rf/openair_rf.ko $dbin/openair_rf.ko
    compilations \
	  lte_noS1_build_oai updatefw \
	  updatefw $dbin/updatefw
    make -C $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build oarf > $dlog/oarf.txt 2>&1
    cp $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/*.oct $dbin
    echo_success "oarf tools compiled"
    cp $OPENAIR_DIR/cmake_targets/tools/init_exmimo2 $dbin
  fi

  if [ "$oaisim" = "1" ] ; then
    dconf=$OPENAIR_DIR/targets/bin

    echo_info "Compiling at_nas_ue"
    [ "$CLEAN" = "1" ] && rm -rf $DIR/at_commands/build
    mkdir -p $DIR/at_commands/build
    cd $DIR/at_commands/build
    cmake ..
    compilations \
      at_commands at_nas_ue \
      at_nas_ue $dbin/at_nas_ue

    echo_info "Compiling oaisim"
    cmake_file=$DIR/oaisim_build_oai/CMakeLists.txt
    cp $DIR/oaisim_build_oai/CMakeLists.template $cmake_file
    echo "set(XFORMS $XFORMS )" >>  $cmake_file
    echo "set(RRC_ASN1_VERSION \"${REL}\")" >>  $cmake_file
    echo "set(ENABLE_VCD_FIFO $VCD_TIMING )" >>  $cmake_file
    echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
    [ "$CLEAN" = "1" ] && rm -rf $DIR/oaisim_build_oai/build
    mkdir -p $DIR/oaisim_build_oai/build
    cd $DIR/oaisim_build_oai/build
    cmake ..
    compilations \
	  oaisim_build_oai oaisim \
	  oaisim $dbin/oaisim.$REL

    # ue_ip driver compilation
    echo_info "Compiling UE specific part (ue_ip driver and usim tools)"
    compilations \
	  oaisim_build_oai ue_ip \
	  CMakeFiles/ue_ip/ue_ip.ko $dbin/ue_ip.ko

    [ "$CLEAN" = "1" ] && rm -rf $DIR/nas_sim_tools/build
    mkdir -p $DIR/nas_sim_tools/build
    cd $DIR/nas_sim_tools/build
    cmake ..
    compilations \
	  nas_sim_tools usim \
	  usim $dbin/usim
    compilations \
	  nas_sim_tools nvram \
	  nvram $dbin/nvram

    # generate USIM data
    if [ -f $dbin/nvram ]; then
      install_nas_tools $dbin $dconf
    else
      echo_warning "not generated UE NAS files: binaries not found"
    fi

    echo_info "Compiling oaisim_nos1"
    cmake_file=$DIR/oaisim_noS1_build_oai/CMakeLists.txt
    cp $DIR/oaisim_noS1_build_oai/CMakeLists.template $cmake_file
    echo "set(XFORMS $XFORMS )" >>  $cmake_file
    echo "set(RRC_ASN1_VERSION \"${REL}\")" >>  $cmake_file
    echo "set(ENABLE_VCD_FIFO $VCD_TIMING )" >>  $cmake_file
    echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
    [ "$CLEAN" = "1" ] && rm -rf $DIR/oaisim_noS1_build_oai/build
    mkdir -p $DIR/oaisim_noS1_build_oai/build
    cd $DIR/oaisim_noS1_build_oai/build
    cmake ..
    compilations \
      oaisim_noS1_build_oai oaisim_nos1 \
      oaisim_nos1 $dbin/oaisim_nos1.$REL

    compilations \
      oaisim_noS1_build_oai rb_tool \
      rb_tool $dbin/rb_tool

    # nasmesh driver compilation
    compilations \
	  oaisim_noS1_build_oai nasmesh \
	  CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko
    #oai_nw_drv
    compilations \
	  oaisim_noS1_build_oai oai_nw_drv \
	  CMakeFiles/oai_nw_drv/oai_nw_drv.ko $dbin/oai_nw_drv.ko

    cmake_file=$DIR/oaisim_mme_build_oai/CMakeLists.txt
    cp $DIR/oaisim_mme_build_oai/CMakeLists.template $cmake_file
    echo "set(XFORMS $XFORMS )" >>  $cmake_file
    echo "set(RRC_ASN1_VERSION \"${REL}\")" >>  $cmake_file
    echo "set(ENABLE_VCD_FIFO $VCD_TIMING )" >>  $cmake_file
    echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
    [ "$CLEAN" = "1" ] && rm -rf $DIR/oaisim_mme_build_oai/build
    mkdir -p $DIR/oaisim_mme_build_oai/build
    cd $DIR/oaisim_mme_build_oai/build
    cmake ..
    compilations \
	  oaisim_mme_build_oai oaisim_mme \
	  oaisim_mme $dbin/oaisim_mme.$REL
  fi

  # EPC compilation
  ##################
  if [ "$EPC" = "1" ] ; then
    echo_info "Compiling EPC"
    # Example HSS and EPC run on the same host
    if [ "$CLEAN" = "1" ]; then
      $OPENAIR_DIR/cmake_targets/tools/build_epc --clean --debug --transport-tcp-only --transport-prefer-tcp --s6a-server
      $OPENAIR_DIR/cmake_targets/tools/build_hss --clean --debug --transport-tcp-only --transport-prefer-tcp --fqdn `hostname --fqdn` --connect-to-mme `hostname --fqdn`
    else
      $OPENAIR_DIR/cmake_targets/tools/build_epc --debug --transport-tcp-only --transport-prefer-tcp --s6a-server
      $OPENAIR_DIR/cmake_targets/tools/build_hss --debug --transport-tcp-only --transport-prefer-tcp --fqdn `hostname --fqdn` --connect-to-mme `hostname --fqdn`
    fi

#   if [ "$INSTALL_SYSTEM_FILES" = "1" ] ;then
#    if [ -f $dbin/hss.conf ] ; then
#      sed -e 's/ *= */=/' $dbin/hss.conf > $dconf/hss.conf.nospace
#      source $dconf/hss.conf.nospace
#      rm -f $dconf/hss.conf.nospace
#      create_hss_database root linux "$MYSQL_user" "$MYSQL_pass" "$MYSQL_db"
#    else
#      echo_warning "not created HSS database: config not found"
#    fi
#  fi
fi

  # Auto-tests
  #####################
  if [ "$OAI_TEST" = "1" ]; then
    echo_info "10. Running OAI pre commit tests (pre-ci) ..."
    $OPENAIR_DIR/cmake_targets/autotests/run_compilation_autotests.bash
    $OPENAIR_DIR/cmake_targets/autotests/run_exec_autotests.bash
  else
    echo_info "10. Bypassing the Tests ..."
  fi
}

main "$@"