#!/bin/bash

MODULES=/usr/local/modules

#
# HELPERS
#
function li_get_ports()
{
        local li=$1
        local ports=""

        case "$li" in
                xhfc-1su|hfc-e1)
                        ports="1"
                        ;;
                xhfc-2su|hfc-2e1)
                        ports="1 2"
                        ;;
                xhfc-2s4u|xhfc-4su)
                        ports="1 2 3 4"
                        ;;
        esac

        echo $ports
}

cfg.parser () {
    local IFS=$'\n' && ini=( $(<$1) )              # convert to line-array
    ini=( ${ini[*]//;*/} )                   # remove comments
    ini=( ${ini[*]/#[/\}$'\n'cfg.section.} ) # set section prefix
    ini=( ${ini[*]/%]/ \(} )                 # convert text2function (1)
    ini=( ${ini[*]/=/=\( } )                 # convert item to array
    ini=( ${ini[*]/%/ \)} )                  # close array parenthesis
    ini=( ${ini[*]/%\( \)/\(\) \{} )         # convert text2function (2)
    ini=( ${ini[*]/%\} \)/\}} )              # remove extra parenthesis
    ini[0]=''                                # remove first element
    ini[${#ini[*]} + 1]='}'                  # add the last brace
    eval "$(echo "${ini[*]}")"               # eval the result
}


function load_module()
{
        local module=$1
        shift
        echo "loading module: $module $@"
        /sbin/insmod $MODULES/$module $@
}


#
#  script
#

FPGA_VER=$(cat /proc/FPGA_VERSION)
if [ "$FPGA_VER" -lt "1" ] ; then
	echo "Your FPGA Version is too old to support HW Bridging"
	HW_BRIDGING=no
fi


declare -a LI

#detect
LI[0]=$(cat /proc/li0 | grep "^type: " | cut -d" " -f2)
LI[1]=$(cat /proc/li1 | grep "^type: " | cut -d" " -f2)



#init values
TDM_CLOCK=4
LIF0_IGNORE_CLOCK=no
LIF1_IGNORE_CLOCK=no


#parse cfg file

#cfg.parser '/usr/conf/isdn.conf'
cfg.parser '/usr/conf/hardware.conf'

#
#check for tdm master
#
if [ "$HW_BRIDGING" != "no" ] ; then
#enable lif0_cfg
cfg.section.lif0
lif0_master=$master
lif0_type=$type

if [ "$lif0_type" = "none" ] ; then
	lif0_master=0
fi

#enable lif1_cfg
cfg.section.lif1
lif1_master=$master
lif1_type=$type

if [ "$lif1_type" = "none" ] ; then
	lif1_master=0
fi

#enable pcm_cfg
cfg.section.pcm
pcm_master=$master


case "${LI[0]}" in
    si-*)
    export lif0_fx=1;
    ;;
    telit-*)
    export lif0_gsm=1;
    ;;
esac

case "${LI[1]}" in
    si-*)
    export lif1_fx=1;
    ;;
    telit-*)
    export lif1_gsm=1;
    ;;
esac

if [ "$FPGA_VER" -lt "7" ] ; then
    if [ "$lif0_master" = "1" -a "$lif1_master" = "1" ] ; then
        TDM_CLOCK=4

        if [ "$lif0_fx" = "1" ] ; then
            TDM_CLOCK=$(($TDM_CLOCK + 8))
        fi
        if [ "$lif1_fx" = "1" ] ; then
            TDM_CLOCK=$(($TDM_CLOCK + 16))
        fi
    elif [ "$lif0_master" = "1" ] ; then
        TDM_CLOCK=1
        if [ "$lif0_fx" = "1" ] ; then
            TDM_CLOCK=$(($TDM_CLOCK + 8))
        fi
    elif [ "$lif1_master" = "1" ] ; then
        TDM_CLOCK=2
        if [ "$lif1_fx" = "1" ] ; then
            TDM_CLOCK=$(($TDM_CLOCK + 16))
        fi
        LIF0_IGNORE_CLOCK=yes
    elif [ "$pcm_master" = "1" ] ; then
        TDM_CLOCK=32
        LIF0_IGNORE_CLOCK=yes
        LIF1_IGNORE_CLOCK=yes
    fi
else
    if [ "$lif0_master" = "1" -a "$lif1_master" = "1" ] ; then
        TDM_CLOCK=4

        #analog stuff
        if [ "$lif0_fx" = "1" ] ; then
            TDM_CLOCK=$(($TDM_CLOCK + 2**15))
        fi
        if [ "$lif1_fx" = "1" ] ; then
            TDM_CLOCK=$(($TDM_CLOCK + 2**21))
        fi
    elif [ "$lif0_master" = "1" ] ; then
        TDM_CLOCK=1
        if [ "$lif0_fx" = "1" ] ; then
            TDM_CLOCK=$(($TDM_CLOCK + 2**15))
        fi
    elif [ "$lif1_master" = "1" ] ; then
        TDM_CLOCK=2
        if [ "$lif1_fx" = "1" ] ; then
            TDM_CLOCK=$(($TDM_CLOCK + 2**21))
        fi
        LIF0_IGNORE_CLOCK=yes
    elif [ "$pcm_master" = "1" ] ; then
        TDM_CLOCK=$((2**4))
        LIF0_IGNORE_CLOCK=yes
        LIF1_IGNORE_CLOCK=yes
    fi
    #gsm stuff
    if [ "$lif0_gsm" = "1" ] ; then
        TDM_CLOCK=$(($TDM_CLOCK + 2**13+2**14+2**15))
    fi
    if [ "$lif1_gsm" = "1" ] ; then
        TDM_CLOCK=$(($TDM_CLOCK + 2**19+2**20+2**21))
    fi
fi

echo "setting TDM_CLOCK to $TDM_CLOCK"
echo -ne $TDM_CLOCK > /proc/TDM_CLOCK_SRC
fi


xhfc_protocol=""
xhfc_layermask=""
xhfc_pcm=0
xhfc_pcm_config=0x90001
#xhfc_pcm_config=0x80001
xhfc_debug=0x0
#xhfc_portswitch=0
xhfc_pcm_conf_base=0x90001

hfcmulti_type="0x800"
hfcmulti_protocol=""
hfcmulti_layermask=""

parameters_xhfc-4su ()
{
    local IFS=$','
    tmp_lm=($ntteSW)
    tmp_pr=($ntteSW)
    tmp_pp=($ptp)
    tmp_hw=($ntteHW)
    tmp_lt=($termination)

    tmp_lm=(${tmp_lm[*]//te/0xf} )
    tmp_lm=(${tmp_lm[*]//nt/0x3} )

    tmp_pr=(${tmp_pr[*]//te/2} )
    tmp_pr=(${tmp_pr[*]//nt/2+2**4})
    tmp_lt=(${tmp_lt[*]//0/2**10})
    tmp_lt=(${tmp_lt[*]//1/0})
    tmp_lt=(${tmp_lt[*]//2**00/2**10})
    tmp_hw=(${tmp_hw[*]//te/0})
    tmp_hw=(${tmp_hw[*]//nt/2**11})
    tmp_pp=(${tmp_pp[*]//1/2**13})

    tmp_clock=(${clock//$clock/$clock*2**20})

    slave=1
    if [ "$master" = "1" ] ; then
            slave=0
    fi
    tmp_master=(${slave//1/2**18})
    tmp_portswitch=(${portswitch:=0})

    xhfc_lm=(${xhfc_lm[*]} ${tmp_lm[*]})
    xhfc_pr=(${xhfc_pr[*]} ${tmp_pr[*]})
    xhfc_lt=(${xhfc_lt[*]} ${tmp_lt[*]})
    xhfc_pp=(${xhfc_pp[*]} ${tmp_pp[*]})
    xhfc_hw=(${xhfc_hw[*]} ${tmp_hw[*]})

    xhfc_clock=(${xhfc_clock[*]} ${tmp_clock[*]})
    xhfc_master=(${xhfc_master[*]} ${tmp_master[*]})
    xhfc_portswitch=(${xhfc_portswitch[*]} ${tmp_portswitch[*]})

    IFS=$'\n'
    for i in $(seq 0 $((${#xhfc_pr[*]}-1))) ; do
       let a="${xhfc_pr[$i]}+${xhfc_lt[$i]}+${xhfc_hw[$i]}+${xhfc_pp[$i]}"
       eval xhfc_prot[$i]=$(printf 0x%x $a)
    done

    for i in $(seq 0 $((${#xhfc_clock[*]}-1))) ; do
       let a="${xhfc_clock[$i]}+$xhfc_pcm_conf_base+${xhfc_master[$i]}"
       eval xhfc_pcm_config[$i]=$(printf 0x%x $a)
    done

    IFS=$','
    tmp=${xhfc_lm[*]}
    tmp=${tmp// /,}
    xhfc_layermask=$tmp

    tmp=${xhfc_prot[*]}
    tmp=${tmp// /,}
    xhfc_protocol=$tmp

    tmp=${xhfc_pcm_config[*]}
    tmp=${tmp// /,}
    xhfc_pcm_config=$tmp

    echo "XHFC S0 lm: $xhfc_layermask prot: $xhfc_protocol pcm_config: $xhfc_pcm_config portswitch: $xhfc_portswitch"
}

parameters_hfc-e1 ()
{
    local IFS=$','
    tmp_pr=($ntteSW)
    tmp_lm=($ntteSW)
    tmp_crc=($crc)

    tmp_lm=(${tmp_lm[*]//te/0xf} )
    tmp_lm=(${tmp_lm[*]//nt/0x3} )

    tmp_pr=(${tmp_pr[*]//te/2} )
    tmp_pr=(${tmp_pr[*]//nt/2+2**4})

    tmp_crc=(${tmp_crc[*]//0/2**23})
    tmp_crc=(${tmp_crc[*]//1/0})

    hfcmulti_lm=(${hfcmulti_lm[*]} ${tmp_lm[*]})
    hfcmulti_pr=(${hfcmulti_pr[*]} ${tmp_pr[*]})
    hfcmulti_crc=(${hfcmulti_crc[*]} ${tmp_crc[*]})

    slave=1
    if [ "$master" = "1" ] ; then
            slave=0
    fi

    if [ "$1" = "2" ] ; then
        hfcmulti_master=(${hfcmulti_master[*]} "0x10001+${slave//1/2**11}" "0x10001+2**11")
    else
        hfcmulti_master=(${hfcmulti_master[*]} "0x10001+${slave//1/2**11}")
    fi

    IFS=$'\n'
    for i in $(seq 0 $((${#hfcmulti_pr[*]}-1))) ; do
       #let a="${hfcmulti_pr[$i]}+${hfcmulti_lt[$i]}+${hfcmulti_hw[$i]}+${hfcmulti_pp[$i]}"
       let a="${hfcmulti_pr[$i]}+${hfcmulti_crc[$i]:-0}"
       eval hfcmulti_prot[$i]=$(printf 0x%x $a)
    done

    for i in $(seq 0 $((${#hfcmulti_master[*]}-1))) ; do
        let a="${hfcmulti_master[$i]}"
        eval hfcmulti_type[$i]=$(printf 0x%x $a)
    done


    IFS=$','
    tmp=${hfcmulti_lm[*]}
    tmp=${tmp// /,}
    hfcmulti_layermask=$tmp

    tmp=${hfcmulti_prot[*]}
    tmp=${tmp// /,}
    hfcmulti_protocol=$tmp

    tmp=${hfcmulti_type[*]}
    tmp=${tmp// /,}
    hfcmulti_type=$tmp

    echo "HFCMULTI E1 lm: $hfcmulti_layermask prot: $hfcmulti_protocol type: $hfcmulti_type"
}

parameters_hfc-2e1 () {
    parameters_hfc-e1 2
}
parameters_xhfcSi-2s02fxs () {
    parameters_xhfc-4su

    local IFS=$','
    fx_portswitch=(${portswitch:=0})
    fx_country=(${country:=FCC})
    fx_boostringer=(${boostringer:=0})
    fx_fastringer=(${boostringer:=0})
}
parameters_si-4fxs () {
    local IFS=$','
    fx_portswitch=(${portswitch:=0})
    fx_country=(${country:=FCC})
    fx_boostringer=(${boostringer:=0})
    fx_fastringer=(${boostringer:=0})
}
parameters_si-4fxo () {
    local IFS=$','
    fx_portswitch=(${portswitch:=0})
    fx_country=(${country:=FCC})
    fx_boostringer=(${boostringer:=0})
    fx_fastringer=(${boostringer:=0})
}

parameters_telit-1GSM () {
    local IFS=$','
    fx_portswitch=(${portswitch:=0})
    fx_country=(${country:=FCC})
}
parameters_telit-2GSM () {
    local IFS=$','
    fx_portswitch=(${portswitch:=0})
    fx_country=(${country:=FCC})
}

parameters_unknown () {
    echo
}

#
# setup LI0
#

#
# setup LI1
#

cfg.section.lif0
parameters_${LI[0]}

cfg.section.lif1
parameters_${LI[1]}

#exit

# load modules
if [ -n "$xhfc_protocol" -o -n "$hfcmulti_protocol" ]
then
        load_module mISDN_core.ko
        load_module mISDN_l1.ko
        load_module mISDN_l2.ko
        load_module l3udss1.ko
fi

load_xhfc-4su() {
        load_module xhfc.ko protocol=$xhfc_protocol layermask=$xhfc_layermask pcm=$xhfc_pcm pcm_config=$xhfc_pcm_config debug=$xhfc_debug portswitch=$xhfc_portswitch
}
load_hfc-e1 () {
        load_module hfcmulti.ko type=$hfcmulti_type protocol=$hfcmulti_protocol layermask=$hfcmulti_layermask

}
load_hfc-2e1 () {
        load_hfc-e1
}

load_si-4fxs (){
	if [ -z "${FXLOADED}" ]; then
		export FXLOADED=1
		mod_opt="portswitch=${fx_portswitch} country=${fx_country} boostringer=${fx_boostringer} fastringer=${fx_fastringer}"
		load_module bnxanalog.ko ${mod_opt}

#		load_module bnxanalog.ko portswitch=$fx_portswitch country=$fx_country boostringer=$fx_boostringer
	fi
}

load_si-4fxo () {
    load_si-4fxs
}
load_xhfcSi-2s02fxs () {
        load_module xhfc.ko protocol=$xhfc_protocol layermask=$xhfc_layermask pcm=$xhfc_pcm pcm_config=$xhfc_pcm_config debug=$xhfc_debug portswitch=$xhfc_portswitch
        load_si-4fxs
}

load_telit-1GSM () {
	load_module bnxgsm.ko
}
load_telit-2GSM () {
	load_module bnxgsm.ko
}

load_unknown () {
        echo
}

if [ "${LI[0]}" = "${LI[1]}" ] ; then
    load_${LI[0]}
else
    if [ "${LI[1]}" = "telit-2GSM" ] ; then
        load_${LI[1]}
        if [ "${LI[0]}" = "si-4fxo" ] ; then
        	load_${LI[0]}
        	rmmod bnxanalog
        	export FXLOADED=""
        	load_${LI[0]}
        else
        	load_${LI[0]}
        fi
    else
        load_${LI[0]}
        load_${LI[1]}
    fi
fi


