#!/bin/sh
#
# Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of The Linux Foundation nor the names of its
#       contributors may be used to endorse or promote products derived from
#       this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED.  IN NO
# EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

echo "Switching to composition Quectel" > /dev/kmsg

if [ "$#" -ge 3 ]; then
    from_adb=$3
else
    from_adb="n"
fi

if [ "$#" -ge 4 ]; then
    qdss_func=$4
fi

ql_run_configfs() {
    usb_vid=0x2C7C
    usb_pid=0x0122
    manu_string="Quectel"
    prod_string="5G Module"
    func_str="ffs.diag,qdss.qdss,gser.0,cser.dun.0,cser.dun.2,gsi.rmnet"
    
    echo start > /tmp/usb_bind_in_progress
    if [ $from_adb = "n" ]
    then
        pkill adbd
        /sbin/launch_adbd start
        sleep 1
    fi
    cd /sys/kernel/config/usb_gadget/g1
    rm os_desc/c* 2> /dev/null
    rm configs/c*/f* 2> /dev/null
    rm -rf configs/c.2 configs/c.3 2> /dev/null

    # -d: dump usb configuration from rawdata to /data/usb
    # -l: dump dbg log configurations from rawdata to filesystem
    ql_usbcfg -d -l

    if [ -f /data/usb/quec_usb_vid ]
    then 
        usb_vid=`cat /data/usb/quec_usb_vid`
    fi
    
    if [ -f /data/usb/quec_usb_pid ]
    then 
        usb_pid=`cat /data/usb/quec_usb_pid`
    fi
    echo $usb_vid > idVendor
    echo $usb_pid > idProduct
    echo 0xA0 > configs/c.1/bmAttributes

    echo "DIAG_SER_RMNET" > configs/c.1/strings/0x409/configuration
    
    if [ -f /data/usb/quec_manufeature ]
    then 
        manu_string=`cat /data/usb/quec_manufeature`
    fi
    echo $manu_string > strings/0x409/manufacturer

    if [ -f /data/usb/quec_product ]
    then 
        prod_string=`cat /data/usb/quec_product`
    fi
    echo $prod_string > strings/0x409/product

    if [ -f /data/usb/quec_usb_maxpower ]
    then
        usb_maxpower=`cat /data/usb/quec_usb_maxpower`
    fi
    echo $usb_maxpower > /sys/kernel/config/usb_gadget/g1/configs/c.1/MaxPower
    
    if [ -f /data/usb/quec_usb_func ]
    then 
        func_str=`cat /data/usb/quec_usb_func`

        # AT+QCFG="usbcfg",0x2C7C,0x0801,0,0,0,0,0,0,0
        if [ -z "$func_str" ]; then
            exit
        fi
    fi

    # 0 ffs.diag  DM
    # 1 cser.nmea.1 NMEA 
    # 2 cser.dun.0 AT
    # 3 cser.dun.2 Modem
    # 4 gsi.rmnet  RMNET
    # 5 ffs.adb    ADB
    # 8 gsi.mbim   MBIM
    # 10 gsi.ecm  ECM
    # 12  QDSS
    # 13  DPL
    # 14 uac1_legacy audio

    funcs=$(echo $func_str |tr "," "\n")
    other_func_index=17

    offset=0
    for func in $funcs; do
        if [ $func == "gsi.rndis" ]; then
            offset=2
            break
        fi
    done

    for func in $funcs
    do
        case $func in 
            gsi.rndis)
                func_index=0
                ;;
            ffs.diag)
                func_index=0
                ;;
            gser.0)
                func_index=1
                ;;
            cser.dun.0)
                func_index=2
                ;;
            cser.dun.2)
                func_index=3
                ;;
            gsi.rmnet)
                func_index=4
                ;;
            ffs.adb)
                func_index=5
                ;;
            gsi.mbim)
                func_index=8
                ;;
            gsi.ecm)
                func_index=10
                ;;
            qdss.qdss)
                func_index=12
                #johnson-20220509, fix qxdm qdss not work issue
                func=qdss.$qdss_func
                ;;
            gsi.dpl)
                func_index=13
                ;;
            uac1_legacy.uac1_legacy1)
                func_index=14
                ;;
            *)
                func_index=$other_func_index
                other_func_index=$((other_func_index+1))
                ;;
        esac

        if [ $func != "gsi.rndis" ] && [ $func_index -le 5 ]; then
            let func_index=$func_index+$offset
        fi
        ln -s functions/$func configs/c.1/f$func_index
    done

    rm -f /tmp/usb_bind_in_progress
    echo "binding UDC with Gadget..." $1
    echo $1 > UDC
    cd /
}

udcname=`ls -1 /sys/class/udc | head -n 1`
ql_run_configfs $udcname
