#!/bin/bash
#
# calvados/fretta_pkg/boot/scripts/pd-functions
# This script provides PD functions to other scripts.
#
# Copyright (c) 2014-2021 by Cisco Systems, Inc.
# All rights reserved.

# source PD-function library
if [ -f /etc/init.d/load_kernel_modules.sh ]; then
    source /etc/init.d/load_kernel_modules.sh
fi

source /etc/init.d/mod_ins/module-load-functions

#
# Get the file size in bytes, cross os
#
function filesize
{
    local file=$1
    size=`stat -c %s $file 2>/dev/null` # linux
    if [ $? -eq 0 ]; then
        echo $size
        return 0
    fi

    eval $(stat -s $file) # macos
    if [ $? -eq 0 ]; then
        echo $st_size
        return 0
    fi

    echo 0
    return -1
}

#
# Check if pd_funcions should be skipped
#
function skip_pd_functions {
    local install=$(cat /proc/cmdline | grep install=)
    if [ -n "${install}" ]; then
        return 1
    fi
    local sim=$(cat /proc/cmdline | grep simulator=)
    if [ -n "${sim}" ]; then
        return 1
    fi
    if [[ "${BOARDTYPE}" == "LC" ]] || [[ "${BOARDTYPE}" == "FC" ]] || [[ "${BOARDTYPE}" == "XC" ]]; then
        return 1
    fi
    return 0
}

#
# Which TTY should calvados con use
#
function platform_enable_calvados_con
{
    skip_pd_functions
    if [ $? -ne 0 ]; then
        return;
    fi
    ACTIVE_SERIAL='/dev/pts/0'
    declare -F platform_log &>/dev/null && platform_log "Calvados console on $ACTIVE_SERIAL"
    echo "Calvados console on $ACTIVE_SERIAL"
}

#
# Which TTY should calvados aux use
#
function platform_enable_calvados_aux
{
    skip_pd_functions
    if [ $? -ne 0 ]; then
        return;
    fi
    ACTIVE_SERIAL='/dev/pts/1'
    declare -F platform_log &>/dev/null && platform_log "Calvados aux on $ACTIVE_SERIAL"
    echo "Calvados aux on $ACTIVE_SERIAL"
}

#
# Which TTY should XR con use
#
function platform_enable_xr_con
{
    skip_pd_functions
    if [ $? -ne 0 ]; then
        return;
    fi
    ACTIVE_SERIAL_XR_CON="pts/0"
    declare -F platform_log &>/dev/null && platform_log "XR console on $ACTIVE_SERIAL_XR_CON"
    echo "XR console on $ACTIVE_SERIAL_XR_CON"
}

#
# Which TTY should XR aux use
#
function platform_enable_xr_aux
{
    skip_pd_functions
    if [ $? -ne 0 ]; then
        return;
    fi
    ACTIVE_SERIAL_XR_AUX="pts/1"
    declare -F platform_log &>/dev/null && platform_log "XR aux on $ACTIVE_SERIAL_XR_AUX"
    echo "XR aux on $ACTIVE_SERIAL_XR_AUX"
}


#
# Should we allow the first serial port to have a tty login?
#
function platform_enable_host_login_on_first_serial
{
    skip_pd_functions
    if [ $? -ne 0 ]; then
        return;
    fi
    ACTIVE_SERIAL=''
}

function platform_is_ttyS0_used
{
    #Following cards used ttyS0
    # 1. P+100
    # 2. P+MPA
    # 3. P+MPA_TCAM
    local card_index=$(get_cmdline_card_index)
    if  [ "$card_index" == 27023 ] || 
        [ "$card_index" == 27034 ] || 
        [ "$card_index" == 27035 ] || 
        [ "$card_index" == 27044 ] ||
        [ "$card_index" == 27050 ] ||
        [ "$card_index" == 27060 ] ||
        [ "$card_index" == 27064 ] ||
        [ "$card_index" == 27046 ] ||
        [ "$card_index" == 27061 ] ||
        [ "$card_index" == 27062 ] ||
        [ "$card_index" == 27063 ] ||
        [ "$card_index" == 27066 ] ||
        [ "$card_index" == 27067 ] ||
        [ "$card_index" == 27068 ] ||
        [ "$card_index" == 27055 ] ; then
        true
    else 
        false
    fi
}

# Do we want to enable host access on extra ttys? Good for development but
# is a security risk to leave host access visible.
#
function platform_starts_serial
{
    # FRETTA_BRINGUP_HACK - CSCut87979
    # Allow starts-serial to start serial login
    # If no active serial set, and on hostos, start serial on ttyS0
    [ -n "$ACTIVE_SERIAL" -o "$VMTYPE" != "hostos" ] || ACTIVE_SERIAL="/dev/ttyS0"

    #FRETTA_BRINGUP_HACK - CSCut90301
    #boardtype FC/XC is not defined yet, use arch as filter
    #FC/XC still uses boardtype as LC
    ARCH=`arch`
    if [ "$ARCH" == "armv7l" ]; then
        BOARDTYPE=$(get_cctrl_board_type)
    fi

    if [ "${BOARDTYPE}" == "FC" ] || [ "${BOARDTYPE}" == "XC" ] ; then
        if [ "$VMTYPE" == "hostos" ]; then
            ACTIVE_SERIAL="/dev/ttyS0"
        else
            ACTIVE_SERIAL="/dev/pts/0"
            if  ! (grep -q "pts/0" /etc/securetty)  ; then
                echo pts/0 >> /etc/securetty
            fi
        fi
        SPEED=115200
    elif [ "${BOARDTYPE}" == "LC" -a "$VMTYPE" != "hostos" ]; then
        ACTIVE_SERIAL="/dev/pts/0"
        if  ! (grep -q "pts/0" /etc/securetty)  ; then
            echo pts/0 >>/etc/securetty
        fi
        SPEED=115200
    elif [ "${BOARDTYPE}" == "LC" ]; then
        if platform_is_ttyS0_used ; then
            ACTIVE_SERIAL="/dev/ttyS0"
            SPEED=115200 
        else 
            ACTIVE_SERIAL="/dev/ttyS1"
            SPEED=115200 
        fi
    fi
    grep -q vmtype=hostos /proc/cmdline && return

    skip_pd_functions
    if [ $? -ne 0 ]; then
        return;
    fi
    #
    # We do not want host tty access unless enabled by development mode,
    # so default to no access.on
    #
    echo "Start serial incoming on $ACTIVE_SERIAL, Clearing .."
    declare -F platform_log &>/dev/null && platform_log "Start serial incoming on $ACTIVE_SERIAL, Clearing .."
    ACTIVE_SERIAL=
}

#
# Check we have somewhere to write logs to. At early boot we might not have
# /var/log, so use /tmp until then
#
function platform_log_choose_log_file
{
    #
    # Where to log shell script output to. If /var/log is not available, use
    # /tmp which surely must be usable.
    #
    local PLATFORM_LOG=/var/log/platform.log

    #
    # If we are installing, append onto the host install logs as platform.log 
    # is not saved by xrnginstall in save_install_log (yet)
    #
    grep -q "root=/dev/ram" /proc/cmdline
    if [ $? -eq 0 ]; then
        PLATFORM_LOG=/var/log/host-install.log
        #
        # A tad obscure, but this is the FD that pxe_install uses for logging.
        # Only if we log to this will our output get into host-install.log
        #
        PLATFORM_LOG=/dev/fd/107
    fi

    PLATFORM_LOG_FILE=$PLATFORM_LOG
    if [ ! -f $PLATFORM_LOG_FILE ]; then
        touch $PLATFORM_LOG_FILE &>/dev/null
    fi

    if [ ! -w $PLATFORM_LOG_FILE ]; then
        local PLATFORM_TMP_LOG=/tmp/platform.early.log

        PLATFORM_LOG_FILE=$PLATFORM_TMP_LOG
    fi

    #
    # Sanity check it doesn't get too large
    #
    if [ -f $PLATFORM_LOG_FILE ]; then
        local FILESIZE=`filesize $PLATFORM_LOG_FILE`
        local MAX=1048576

        if [ $FILESIZE -ge $MAX ]; then
            #
            # Chop off the start of the file
            #
            sed -i '1,100d' $PLATFORM_LOG_FILE
        fi
    fi
}

#
# Utility function to log to our platform log file to help with
# debugging shell script flow.
#
function platform_log
{
    platform_log_choose_log_file

    local DATE=`date`
    echo "$DATE ($0): $*" >> $PLATFORM_LOG_FILE
}

#
# Utility function to log to our platform log file to help with
# debugging shell script flow.
#
function platform_log_error
{
    platform_log_console $*

    backtrace
}

#
# Some calvados scripts use log message but it is not defined. Get the output
# into our platform log if log_message is not defined.
#
function log_message
{
    platform_log $*
}

#
# Log to file and console
#
function platform_log_console 
{
    platform_log_choose_log_file

    local DATE=`date`
    echo "$DATE ($0): $*" | tee -a $PLATFORM_LOG_FILE

    return ${PIPESTATUS[0]}
}

#
# Keep this function aliased as a variable, so that if PLATFORM_LOG_EXEC is 
# not defined due to an error in including this file, the callers command 
# still executes
#
PLATFORM_LOG_EXEC=platform_log_exec
PLATFORM_LOG_EXEC_CONSOLE=platform_log_exec_console

#
# Log results to the log file only
#
function platform_log_exec
{
    platform_log_choose_log_file
    platform_log "exec: $*"
    platform_log "    : in cwd" `pwd`

    local PREFIX="`date -u`: -- "
    $* 2>&1 | sed "s/^/${PREFIX}/g" >>$PLATFORM_LOG_FILE 2>&1

    return ${PIPESTATUS[0]}
}

#
# Log results to the log file and the console
#
function platform_log_exec_console
{
    platform_log_choose_log_file
    platform_log "exec: $*"
    platform_log "    : in cwd" `pwd`

    local PREFIX="`date -u`: -- "
    $* 2>&1 | sed "s/^/${PREFIX}/g" | tee -a $PLATFORM_LOG_FILE

    return ${PIPESTATUS[0]}
}

#
# Print a shell backtrace
#
function backtrace () {
    local deptn=${#FUNCNAME[@]}

    for ((i=1; i<$deptn; i++)); do
        local func="${FUNCNAME[$i]}"
        local line="${BASH_LINENO[$((i-1))]}"
        local src="${BASH_SOURCE[$((i-1))]}"
        printf '%*s at: %s(), %s, line %s\n' $i '' $func $src $line # indent
    done
}

function platform_log_backtrace_ () {
    local depth=${#FUNCNAME[@]}

    for ((i=1; i<$depth; i++)); do
        local func="${FUNCNAME[$i]}"
        local line="${BASH_LINENO[$((i-1))]}"
        local src="${BASH_SOURCE[$((i-1))]}"
        printf '%*s at: %s(), %s, line %s\n' $i '' $func $src $line >> $PLATFORM_LOG_FILE
    done
}

function platform_log_backtrace () {
    platform_log_choose_log_file

    platform_log_backtrace_
}

# This will help the CAPI and GSP packets to get proper priority
function set_vlan_priority_map() {
    local dev=$1
    for i in {0..7}
    do
       vconfig set_egress_map $dev $i $i  > /dev/null 2>&1
       vconfig set_ingress_map $dev $i $i  > /dev/null 2>&1
    done
}
 
# Console Mux details
# Console muxing is needed becase there is only one console
#
function platform_get_mux_tty_settings
{
    source /etc/init.d/spirit_pd.sh
    get_board_type
    if [ "${BOARDTYPE}" == "RP" ]; then
        MUX_TTY=/dev/ttyS0
        MUX_TTY_SPEED=9600  
        local card_index=$(get_cmdline_card_index)
         if  [ "$card_index" == 27065 ]; then
            MUX_TTY_SPEED=115200
         fi
        MUX_TTY_TYPE=3
        MUX_TTY_FLOWCTRL=""
        MUX_TTY_SOCAT_OPTION="raw,echo=0,opost=1"
    fi
}

# App hosting Cgroup settings
function pd_tpa_cgroup_settings
{
    APP_CGROUP_MEM_NUMA_NODES=0
    APP_CGROUP_CPUSET_CPUS=1-11
    APP_CGROUP_CPU_SHARES=256
    APP_CGROUP_MEM_LIMIT_IN_BYTES=1G
}

#
# For Tortin We have two variants 16G and 32G ,default sdr-xml is
# aligned to 32G so check and override the xml config if running
# on 16G board.
#
function platform_calvados_sdr_xml_check
{

    #
    # Find the calvados xml (from the host)
    #
    ROOTFS="/lxc_rootfs/panini_vol_grp-calvados_lv0"
    DEFAULT_SDR_XML="default_sdr.xml"
    TORTIN_16G_SDR_XML="tortin_16g_default_sdr.xml"

    # Read the symlink
    OPT_DEFAULT_SDR_XML="/opt/cisco/calvados/confd/var/confd/cdb/$DEFAULT_SDR_XML"
    OPT_DEFAULT_SDR_XML="${ROOTFS}${OPT_DEFAULT_SDR_XML}"
    OPT_DEFAULT_SDR_XML="$(readlink $OPT_DEFAULT_SDR_XML)"
    OPT_DEFAULT_SDR_XML="${ROOTFS}${OPT_DEFAULT_SDR_XML}"
 

    OPT_TORTIN_16G_SDR_XML="/opt/cisco/calvados/etc/$TORTIN_16G_SDR_XML"
    OPT_TORTIN_16G_SDR_XML="${ROOTFS}${OPT_TORTIN_16G_SDR_XML}"
    OPT_TORTIN_16G_SDR_XML="$(readlink $OPT_TORTIN_16G_SDR_XML)"
    OPT_TORTIN_16G_SDR_XML="${ROOTFS}${OPT_TORTIN_16G_SDR_XML}"

    local plat_type=$(iofpga_reg_read 0 4)
    local num=$( printf "0x%x" $plat_type )
    local result=$(($(( num >> 23 & 0x1 )) << 4 | $(( num >> 28 & 0xF ))))
    if [ $result -eq 23 ]
    then
        echo "TORTIN 16G board"
        cp $OPT_TORTIN_16G_SDR_XML $OPT_DEFAULT_SDR_XML
         sync
    fi
}

# function be called from post_xr_launch,
# need setenv for ACTION and pass to mtd_passthrough.sh 
function platform_post_xr_launch
{
    ACTION=add /usr/bin/mtd_passthrough.sh ubi5
    ACTION=add /usr/bin/mtd_passthrough.sh ubi5_0

    if [ "$VMTYPE" == "hostos" ]; then
        if [ -e /sys/class/net/xr-eth0 ]; then
            ifconfig xr-eth0 mtu 9702
        fi
        if [ -e /sys/class/net/xr-eth1 ]; then
            ifconfig xr-eth1 mtu 9702
        fi
        if [ -e /sys/class/net/xr-eth2 ]; then
            ifconfig xr-eth2 mtu 9702
        fi
        if [ -e /sys/class/net/xr-eth3 ]; then
            ifconfig xr-eth3 mtu 9702
        fi
        if [ -e /sys/class/net/xr-eth4 ]; then
            ifconfig xr-eth4 mtu 9702
        fi
        if [ -e /sys/class/net/xr-eth5 ]; then
            ifconfig xr-eth5 mtu 9702
        fi
        if [ -e /sys/class/net/xr-eth6 ]; then
            ifconfig xr-eth6 mtu 9702
        fi
        if [ -e /sys/class/net/xr-eth7 ]; then
            ifconfig xr-eth7 mtu 9702
        fi
        if [ -e /sys/class/net/xr-eth8 ]; then
            ifconfig xr-eth8 mtu 9702
        fi
        if [ -e /sys/class/net/sysadmin-eth0 ]; then
            ifconfig sysadmin-eth0 mtu 9702
        fi
        if [ -e /sys/class/net/sysadmin-eth1 ]; then
            ifconfig sysadmin-eth1 mtu 9702
        fi
   fi 

   if [ -e /sys/class/net/xr-eth-lc-spp ]; then
       local MY_MOD_ID_HEX=`printf "%X" $(($(my_slot_id) - 1))`
       local spp_lc_mac="4e:41:50:00:$MY_MOD_ID_HEX:01"
       ifconfig xr-eth-lc-spp mtu 9698
       bridge fdb add $spp_lc_mac dev xr-eth-lc-spp master temp
   fi

}

