#!/bin/sh

modem_name() {
    [ -e /app/config/4g_modem ] && cat /app/config/4g_modem || echo "none"
}

modem_dev() {
    [ -e /tmp/4g_modem_tty ] && cat /tmp/4g_modem_tty || echo "none"
}

find_4g_ttydev() {
    local curcnt=0
    local maxcnt="$1"
    local pdir0="/sys/bus/usb-serial/drivers/ch341-uart"
    local pdir1="/sys/bus/usb-serial/drivers/cp210x"
    local jdx=0

    while [ ${jdx} -lt 16 ] ; do
        local ttydev="/dev/ttyUSB${jdx}"
        if [ ! -c ${ttydev} ] ; then
            let "jdx++"
            continue
        fi
        if [ -e "${pdir0}/ttyUSB${jdx}" -o "${pdir1}/ttyUSB${jdx}" ] ; then
            let "jdx++"
            continue
        fi
        let "curcnt++"
        if [ ${curcnt} -ge ${maxcnt} ] ; then
            echo -n "/dev/ttyUSB${jdx}"
            return 0
        fi
        let "jdx++"
    done
    return 0
}

symlink_tty_serial() {
    local pdir="$1"
    [ -z "${pdir}" ] && pdir="/sys/bus/usb-serial/drivers/ch341-uart"
    [ ! -d "${pdir}" ] && return 0

    local idx=1
    local jdx=0
    while [ ${jdx} -lt 16 ] ; do
        if [ ! -e "${pdir}/ttyUSB${jdx}" ] ; then
            let "jdx++"
            continue
        fi
        local devn="/dev/ttyUSB${jdx}"
        if [ ! -e "${devn}" ] ; then
            echo "Error, device not found: ${devn}"
        else
            local devm="/dev/ttysym${idx}"
            [ -e "${devm}" ] && rm -rf "${devm}"
            ln -s -v "${devn}" "${devm}"
            let "idx++"
        fi
        let "jdx++"
    done
}

function init_usbdev() {
    local board=$(board_name)
    local first_time=0

    # identify hardware model
    # get 4G modem info
    if [ ! -f "/app/config/4g_modem" ]; then
        first_time=1

        # wait until we can detect the USB device
        i=1
        while [ $i -le 30 ]; do
            sleep 1
            let i++
            longsung=$(lsusb | grep 1c9e:)
            quectel_EC2X=$(lsusb | grep 2c7c:0125)
            quectel_EC200=$(lsusb | grep 2c7c:6026)
            quectel_EC200S=$(lsusb | grep 2c7c:6002)
            quectel_RM500Q=$(lsusb | grep 2c7c:0800)
            fibocom_FG650_CN=$(lsusb | grep 2cb7:0a06)
            simcom_7600ce_first=$(lsusb | grep 1e0e:9001)
            simcom_7600ce=$(lsusb | grep 1e0e:9011)
            MH5001_5G=$(lsusb | grep 1782:4058)
            RG200U=$(lsusb | grep 2c7c:0900)
            Air720=$(lsusb | grep 1286:4e3d)
            Air724UG=$(lsusb | grep 1782:4e00)
            meigSLM790=$(lsusb | grep 2dee:4d20)
            if [ -n "$longsung" -o \
                -n "$quectel_EC2X" -o \
                -n "$Air720" -o \
                -n "$Air724UG" -o \
                -n "$quectel_EC200" -o \
                -n "$quectel_EC200S" -o \
                -n "$quectel_RM500Q" -o \
                -n "$fibocom_FG650_CN" -o \
                -n "$simcom_7600ce_first" -o \
                -n "$simcom_7600ce" -o \
                -n "${meigSLM790}" -o \
                -n "${RG200U}" -o \
                -n "${MH5001_5G}" ] ; then
                echo "find a 4G modem"
                break
            fi
        done
    else
        mname=$(modem_name)
        eval $mname=1
    fi

    case "$board" in
    WOOLINK-MT7621-512M-256M)
        # wait until we can detect the USB device
        i=1
        while [ $i -le 30 ]; do
            sleep 1
            let i++
            ftdi=$(lsusb | grep 0403:6011)
            if [ -n "$ftdi" ]; then
                break
            fi
        done
        #FTDI USB Serial Device converter under USB 1-2
        local ftdi_path="/sys/bus/usb-serial/drivers/ftdi_sio"
        if [ -d $ftdi_path ]; then
            local ftdi_index=0

            for line in $(find $ftdi_path -name "ttyUSB*" -maxdepth 1 | xargs ls -d); do
                result=$(echo $line | grep "ttyUSB")
                if [[ "$result" != "" ]]; then
                    local tty_dev=${line##*/}
                    echo "link /dev/$tty_dev -> /dev/ttyFTDI$ftdi_index"
                    ln -s /dev/$tty_dev /dev/ttyFTDI$ftdi_index
                    ftdi_index=$(expr $ftdi_index + 1)
                fi
            done
        fi

        # GSM modem converter
        local option_path="/sys/bus/usb-serial/drivers/option1"
        if [ -d $option_path ]; then
            local modem_index=0

            for line in $(find $option_path -name "ttyUSB*" -maxdepth 1 | xargs ls -d); do
                result=$(echo $line | grep "ttyUSB")
                if [[ "$result" != "" ]]; then
                    local tty_dev=${line##*/}
                    echo "link /dev/$tty_dev -> /dev/ttyMODEM$modem_index"
                    ln -s /dev/$tty_dev /dev/ttyMODEM$modem_index
                    modem_index=$(expr $modem_index + 1)
                fi
            done
        fi
        ;;
    esac

    local dev_path=""
    local init_gcom=""
    local init_gcom2=""
    local name="None"
    if [ -n "$simcom_7600ce_first" -o -n "$simcom_7600ce" ]; then
        dev_path="/dev/ttyUSB2"
        i=1
        while [ $i -le 30 ]; do
            sleep 1
            let i++
            if [ -w "$dev_path" ]; then
                break
            fi
        done

        i=1
        while [ $i -le 30 ]; do
            sleep 1
            let i++
            simcom_7600ce_first_tmp=$(lsusb | grep 1e0e:9001)
            simcom_7600ce_tmp=$(lsusb | grep 1e0e:9011)
            if [ -n "$simcom_7600ce_first_tmp" -o -n "$simcom_7600ce_tmp" ]; then
                echo "find matched simcom"
                break
            fi
        done

        if [ -n "$simcom_7600ce_first_tmp" ]; then
            name="simcom_7600ce_first"
            sleep 10
            i=1
            while [ $i -le 30 ]; do
                let i++
                comgt -d $dev_path -s /etc/gcom/sim7600_init.gcom 2>&1 | tee /app/modem_init$i.log
                result=$(cat /app/modem_init$i.log | grep "OK")
                if [ -n "$result" ]; then
                    sleep 1
                    break
                fi
            done
            first_time=1 # force reinit the modem, should not this id after initialized
        elif [ -n "$simcom_7600ce_tmp" ]; then
            name="simcom_7600ce"
            if [ -n "$simcom_7600ce_first" ]; then
                first_time=1
            fi
        fi
    elif [ -n "$quectel_EC2X" ]; then
        case "$board" in
        WOOLINK-MT7621-512M-256M)
            dev_path="/dev/ttyMODEM2"
            ;;
        *)
            dev_path="/dev/ttyUSB2"
            ;;
        esac
        init_gcom="/etc/gcom/ec2x.gcom"
        name="quectel_EC2X"
    elif [ -n "$fibocom_FG650_CN" ]; then
        dev_path="/dev/ttyUSB0"
        init_gcom="/etc/gcom/FG650-CN_INIT.gcom"
        name="fibocom_FG650_CN"
    elif [ -n "$quectel_RM500Q" ]; then
        case "$board" in
        WOOLINK-MT7621-512M-256M)
            dev_path="/dev/ttyMODEM2"
            ;;
        *)
            dev_path="/dev/ttyUSB2"
            ;;
        esac
        init_gcom="/etc/gcom/rm500q.gcom"
        name="quectel_RM500Q"
    elif [ -n "$quectel_EC200" ]; then
        case "$board" in
        WOOLINK-MT7621-512M-256M)
            dev_path="/dev/ttyMODEM2"
            ;;
        *)
            dev_path="/dev/ttyUSB2"
            ;;
        esac
        init_gcom="/etc/gcom/ec200.gcom"
        name="quectel_EC200"
    elif [ -n "$quectel_EC200S" ]; then
        case "$board" in
        WOOLINK-MT7621-512M-256M)
            dev_path="/dev/ttyMODEM2"
            ;;
        *)
            dev_path="/dev/ttyUSB2"
            ;;
        esac
        init_gcom="/etc/gcom/ec200.gcom"
        name="quectel_EC200S"
    elif [ -n "$Air720" ]; then
        name="Air720"
        dev_path="/dev/ttyUSB1"
        init_gcom="/etc/gcom/air720.gcom"
    elif [ -n "$Air724UG" ]; then
        name="Air724UG"
        dev_path="/dev/ttyUSB1"
    elif [ -n "$longsung" ]; then
        name="longsung"
    elif [ -n "${meigSLM790}" ] ; then
        name="meigSLM790"
        dev_path="/dev/ttyUSB1"
    elif [ -n "${RG200U}" ] ; then
        name="RG200U"
        dev_path=$(find_4g_ttydev 3)
        init_gcom="/etc/gcom/rg200u.gcom"
    elif [ -n "${MH5001_5G}" ] ; then
        name="MH5001_5G"
        dev_path=$(find_4g_ttydev 1)
        init_gcom="/etc/gcom/mh5001_5g.gcom"
        [ -e "${dev_path}" ] && stty -F "${dev_path}" echo raw
        if [ -e '/sys/bus/usb-serial/drivers/generic/new_id' ] ; then
            echo 1782 4058 > /sys/bus/usb-serial/drivers/generic/new_id
        fi
    fi

    if [ $first_time == "1" ]; then
        if [ -n "$init_gcom" ]; then
            # need run init script
            i=1
            while [ $i -le 30 ]; do
                sleep 1
                let i++
                if [ -w "$dev_path" ]; then
                    break
                fi
            done
            sleep 15
            comgt -d $dev_path -s $init_gcom 2>&1 | tee /app/modem_init.log
        fi

        if [ -n "$init_gcom2" ]; then
            # need run init script
            i=1
            while [ $i -le 30 ]; do
                sleep 1
                let i++
                if [ -w "$dev_path" ]; then
                    break
                fi
            done
            sleep 3
            comgt -d $dev_path -s $init_gcom2 2>&1 | tee /app/modem_init2.log
        fi

        echo $name >/app/config/4g_modem
    fi
    echo $dev_path >/tmp/4g_modem_tty
}

function enter_simcard_pin_code() {
    dev=$(modem_dev)

    if [ -f "/app/config/sim_pin_code" ]; then
        pin=$(cat /app/config/sim_pin_code)
        export PINCODE=$pin
        gcom -d $dev -s /etc/gcom/setpin.gcom
    fi
}

function reset_modem() {
    dev=$(modem_dev)
    board=$(board_name)

    i=1
    while [ $i -le 30 ]; do
        sleep 1
        let i++
        if [ -w "$dev" ]; then
            echo -e "AT+RESET\r\n" >$dev
            break
        fi
    done

    case "$board" in
    WOOLINK-MT7628-128M-32M)
        echo 5 >/sys/class/gpio/export
        echo out >/sys/class/gpio/gpio5/direction
        echo 0 >/sys/class/gpio/gpio5/value
        sleep 1
        echo 1 >/sys/class/gpio/gpio5/value
        ;;
    esac
}

hw_setup_gpio() {
    local gnum="$1"
    local gdir="/sys/class/gpio/gpio${gnum}"
    [ ! -e "${gdir}" ] && \
        echo "${gnum}" > '/sys/class/gpio/export'
    if [ ! -e "${gdir}" ] ; then
        echo "Error, failed to export GPIO '${gnum}'" 1>&2
        return 1
    fi
    echo "$2" > "${gdir}/direction"
    return $?
}

hwset_output() {
    local gnum="$1"
    local gval="$2"
    hw_setup_gpio "${gnum}" "out"
    echo "${gval}" > "/sys/class/gpio/gpio${gnum}/value"
    return $?
}

function init_hardware_gpio() {
    local bname="$(board_name)"
    if [ "${bname}" = "WooLink2F6280_W_4G" ] ; then
        hwset_output 3 1 # set GPIO1_03 to HIGH, to enable INPUT Pins
        hwset_output 124 0 # GPIO4_28
        hwset_output 122 0 # GPIO4_26
        hwset_output 121 0 # GPIO4_25
        hwset_output 118 0 # GPIO4_22
        hwset_output 117 0 # GPIO4_21
        hwset_output 119 0 # GPIO4_23
        hwset_output 120 0 # GPIO4_24
        hwset_output 123 0 # GPIO4_27
        hw_setup_gpio 81 'in' # GPIO3_17
        hw_setup_gpio 79 'in' # GPIO3_15
        hw_setup_gpio 77 'in' # GPIO3_13
        hw_setup_gpio 75 'in' # GPIO3_11
        hw_setup_gpio 73 'in' # GPIO3_09
        hw_setup_gpio 71 'in' # GPIO3_07
        hw_setup_gpio 69 'in' # GPIO3_05
        hw_setup_gpio 65 'in' # GPIO3_01
        hw_setup_gpio 66 'in' # GPIO3_02
        hw_setup_gpio 68 'in' # GPIO3_04
        hw_setup_gpio 78 'in' # GPIO3_14
        hw_setup_gpio 76 'in' # GPIO3_12
        hw_setup_gpio 72 'in' # GPIO3_08
        hw_setup_gpio 70 'in' # GPIO3_06
        hw_setup_gpio 67 'in' # GPIO3_03
        hw_setup_gpio 64 'in' # GPIO3_00
    fi
    return 0
}

function init_hardware_info() {
    init_usbdev
    symlink_tty_serial
    enter_simcard_pin_code
    modem=$(modem_name)
    case "$modem" in
    quectel_*)
        reset_modem
        ;;
    meigSLM790)
        if [ -c '/dev/ttyUSB0' ] ; then
            # disconnect first
            # echo -e -n 'at^ndisdup=1,0\n' > '/dev/ttyUSB0'
            # sleep 1 # delay one second
            # connect to 4G network now
            echo -e -n 'at^ndisdup=1,1\n' > '/dev/ttyUSB0'
        fi
        ;;
    *)
        echo "do not reset"
        ;;
    esac

    init_hardware_gpio
}
