#!/bin/sh

#
# Copyright (C) 2011 shibby
#


PREFIX=$1

PID=$$
PIDFILE="/var/run/switch3g.pid"
DETECTFILE="/tmp/3g.detect"
MODE=`nvram get "$PREFIX"_proto`
DEVNR=`nvram get "$PREFIX"_modem_dev`


if [ -z "$PREFIX" ]; then
    echo "usage: switch3g INTERFACE"
    exit 0
fi

if [ "$MODE" == "lte" ]; then
    exit 0
fi


switchMode() {
    logger -t switch3g[$PID] "3G MODEM - detecting ..."

    # check if modem is already found
    MODULES="cdc_acm option sierra usbserial"

    for MODULE in $MODULES; do
        if [ `cat /proc/bus/usb/devices | grep Driver | grep $MODULE | wc -l` -gt 0 ]; then

            MODULE=`echo $MODULE | tr "_" "-"`

            logger -t switch3g[$PID] "3G MODEM already found - using $MODULE module"
            nvram set 3g_module=$MODULE
            return 1
        fi
    done

    #modem not found, try to detect it
    DEVICES=`lsusb | awk '{print $6}'`

    for SWITCH in $DEVICES; do
        SEARCH=`ls /etc/usb_modeswitch.d/$SWITCH | wc -l`

        # vendor:product

        if [ "$SEARCH" -eq 1 ]; then
            logger -t switch3g[$PID] "3G MODEM FOUND - $SWITCH - Switching ..."

            DV=`echo $SWITCH | cut -d ":" -f1`
            DP=`echo $SWITCH | cut -d ":" -f2`
            /usr/sbin/usb_modeswitch -Q -c /etc/usb_modeswitch.d/$SWITCH -v $DV -p $DP

            # need few seconds before modem will be detected once again after switch
            sleep 6

            VENDOR=`cat /etc/usb_modeswitch.d/$SWITCH | grep "TargetVendor" | cut -d "=" -f2 | cut -d "x" -f2`
            if [ "$VENDOR" == "" ]; then
                VENDOR=`echo $SWITCH | cut -d ":" -f1`
            fi

            PRODUCT=`lsusb | awk '{print $6}' | grep $VENDOR | cut -d ":" -f2`
            if [ "$PRODUCT" != "" ]; then
               logger -t switch3g[$PID] "3G MODEM ready - $VENDOR:$PRODUCT"
               echo "$VENDOR:$PRODUCT" > $DETECTFILE
            fi
        fi
    done

    #trying option and sierra module first
    modprobe cdc-acm
    modprobe option
    modprobe sierra
    sleep 3
    DEV0=`cat /proc/bus/usb/devices | grep Driver | grep cdc_acm | wc -l`
    DEV1=`cat /proc/bus/usb/devices | grep Driver | grep option | wc -l`
    DEV2=`cat /proc/bus/usb/devices | grep Driver | grep sierra | wc -l`

    if [ "$DEV0" -gt 0 ]; then
        logger -t switch3g[$PID] "3G MODEM ready - using cdc-acm module"

        nvram set 3g_module=cdc-acm
        return 1

    elif [ "$DEV1" -gt 0 ]; then
        logger -t switch3g[$PID] "3G MODEM ready - using option module"

        nvram set 3g_module=option
        return 1

    elif [ "$DEV2" -gt 0 ]; then
        logger -t switch3g[$PID] "3G MODEM ready - using sierra module"

        nvram set 3g_module=sierra
        return 1

    else
        logger -t switch3g[$PID] "3G MODEM not found by cdc-acm, option or sierra module. Trying usbserial ..."

        #modprobe -r cdc_acm //we can`t do that. I don`t know why...
        modprobe -r sierra
        modprobe -r option
        modprobe -r cdc-acm

        IS_VENDOR=`echo $VENDOR | wc -w`
        if [ "$IS_VENDOR" -gt 0 ]; then
            IS_PRODUCT=`echo $PRODUCT | wc -w`

            if [ "$IS_PRODUCT" -gt 0 ]; then
                logger -t switch3g[$PID] "3G MODEM - loading module usbserial"
                modprobe -r usbserial
                sleep 1
                insmod usbserial vendor=0x$VENDOR product=0x$PRODUCT
                echo "$VENDOR:$PRODUCT" > $DETECTFILE
                sleep 2
            fi
        fi

        DEV=`cat /proc/bus/usb/devices | grep Driver | grep usbserial | wc -l`
        if [ "$DEV" -gt 0 ]; then
            logger -t switch3g[$PID] "3G MODEM ready - using usbserial module [1]"
            nvram set 3g_module=usbserial
            return 1
        elif [ -f $DETECTFILE ]; then
            VENDOR=`cat $DETECTFILE | cut -d ":" -f1`
            PRODUCT=`cat $DETECTFILE | cut -d ":" -f2`
            TEST3=`lsusb | grep $VENDOR | grep $PRODUCT | wc -l`

            if [ "$TEST3" == "1" ]; then
                logger -t switch3g[$PID] "3G MODEM FOUND - already switched - Last known $VENDOR:$PRODUCT"

                DEV=`cat /proc/bus/usb/devices | grep Driver | grep usbserial | wc -l`
                if [ "$DEV" -gt 0 ]; then
                    logger -t switch3g[$PID] "3G MODEM ready - using usbserial module [2]"
                    nvram set 3g_module=usbserial
                    return 1
                else
                    logger -t switch3g[$PID] "3G MODEM - loading usbserial module"
                    modprobe -r usbserial
                    sleep 1
                    insmod usbserial vendor=0x$VENDOR product=0x$PRODUCT
                    echo "$VENDOR:$PRODUCT" > $DETECTFILE
                    nvram set 3g_module=usbserial
                    return 1
                fi
            fi
        else
            #last chance. try to load usbserial for each usb device
            DEVICES=`lsusb | awk '{print $6}'`

            for SWITCH in $DEVICES; do

                VENDOR=`echo $SWITCH | cut -d ":" -f1`
                PRODUCT=`echo $SWITCH | cut -d ":" -f2`
                modprobe -r usbserial
                sleep 1
                insmod usbserial vendor=0x$VENDOR product=0x$PRODUCT
                sleep 2

                DEV=`cat /proc/bus/usb/devices | grep Driver | grep usbserial | wc -l`

                if [ "$DEV" -gt 0 ]; then
                    logger -t switch3g[$PID] "3G MODEM ready - using usbserial module [3]"
                    nvram set 3g_module=usbserial
                    echo "$VENDOR:$PRODUCT" > $DETECTFILE
                    return 1
                fi
            done
        fi
    fi
    return 0
}

setPIN() {
    PIN=`nvram get "$PREFIX"_modem_pin`
    IS_PIN=`nvram get "$PREFIX"_modem_pin | wc -w`

    if [ "$IS_PIN" == "1" ]; then
        PINCODE="$PIN" gcom -d /dev/$DEVNR -s /etc/gcom/setpin.gcom
    fi
}

checkPid() {
    if [ -f $PIDFILE ]; then

        PIDNO=$(cat $PIDFILE)
        cat "/proc/$PIDNO/cmdline" > /dev/null 2>&1

        if [ $? -eq 0 ]; then
            logger -t switch3g[$PID] "3G MODEM - another proces in action - exiting"
            exit 0
        else
            # Process not found assume not running
            echo $PID > $PIDFILE
            if [ $? -ne 0 ]; then
                logger -t switch3g[$PID] "3G MODEM - could not create PID file"
                exit 0
            fi
        fi
    else
        echo $PID > $PIDFILE
        if [ $? -ne 0 ]; then
            logger -t switch3g[$PID] "3G MODEM - could not create PID file"
            exit 0
        fi
    fi
}

signal() {
    #check signal strength
    CSQ=`gcom -d /dev/$DEVNR -s /etc/gcom/getstrength.gcom | grep "CSQ:" | cut -d " " -f2 | cut -d "," -f1`
    DBM=$((-113+CSQ*2))
    logger -t switch3g[$PID] "3G MODEM Signal Strength: $DBM dBm"
}


###################################################


#check pid file
checkPid

# detect modem
switchMode

if [ $? -eq 1 ]; then
    setPIN
    signal
    service $PREFIX restart
 else
    logger -t switch3g[$PID] "3G MODEM not found ..."
fi

#remove pid file
rm -f $PIDFILE > /dev/null 2>&1
