# (c) 2010-2016 Cezary Jackiewicz <cezary@eko.one.pl>
# (c) 2020-2025 modified by Konstantine Shevlyakov  <shevlakov@132lan.ru>
# (c) 2021-2025 modified by Vladislav Kadulin  <spanky@yandex.ru>


RES="/usr/share/modeminfo"
#GSCRIPT="$RES/scripts/${FAMILY}.txt"

function get_device_info() {
	DEVPORT=$(uci -q get modeminfo.@modeminfo[${s}].device)
	case $DEVPORT in
		!*tty*) get_port ;;
	esac
	modem_family
	GSCRIPT="$RES/scripts/${FAMILY}.at"
	O=$(atinout $GSCRIPT $DEVPORT - |grep -v '^$')
}

function get_port() {
	devices="$(ls /dev/ttyUSB* /dev/ttyACM* /dev/ttyHS* 2>/dev/null | sort -r)"
		for d in $devices; do
			DEVPORT=$d gcom -s $RES/scripts/probeport.gcom > /dev/null 2>&1
			if [ $? = 0 ]; then
				uci set modeminfo.@modeminfo[${s}].device="$d"
				uci commit modeminfo
				break
			fi
		done
	DEVPORT=$(uci -q get modeminfo.@modeminfo[${s}].device)
	O=$(atinout $GSCRIPT $DEVPORT - |grep -v '^$')
}

function modem_family() {
    FAMILY=$(uci -q get modeminfo.@modeminfo[${s}].device | awk -F/ -v res="$RES" '
        function read_file(path) {
            value = ""
            if ((getline value < path) > 0) {
                close(path)
                return value
            }
            return ""
        }
        
        {
            comport = $NF
            if (comport ~ /ttyUSB|ttyHS/) {
                device_path = "/sys/class/tty/" comport "/device/../.."
            } else if (comport ~ /ttyACM/) {
                device_path = "/sys/class/tty/" comport "/device/.."
            } else {
                print "GENERIC"
                exit
            }
            
            vid = read_file(device_path "/idVendor")
            pid = read_file(device_path "/idProduct")
            
            if (vid == "" || pid == "") {
                print "GENERIC"
                exit
            }
            
            vidpid = vid pid
            modem_list = res "/modem.list"
            
           # Read modem.list file
            while ((getline line < modem_list) > 0) {
                if (line ~ /^#/ || line == "") continue
                split(line, parts, ";")
                if (parts[1] == vidpid) {
                    close(modem_list)
                    print toupper(parts[2])
                    exit
                }
            }
            close(modem_list)
            print "GENERIC"
        }
    ')
}

# get CSQ
function get_csq(){
    eval $(echo "$O" | awk -F[:,] '
        /^\+CSQ/ {
            csq = $2
            if (csq == "" || csq < 0 || csq > 31) {
                print "CSQ=-1; CSQ_PER=0; CSQ_COL=\"black\"; CSQ_RSSI=0"
                exit
            }
            
            # Percentage calc
            csq_per = int(csq * 100 / 31)
            
            # Color
            if (csq >= 20) csq_col = "green"
            else if (csq >= 15) csq_col = "orange" 
            else if (csq >= 10) csq_col = "red"
            else csq_col = "red"
            
            # RSSI calc
            csq_rssi = 2 * csq - 113
            
            printf "CSQ=%d; CSQ_PER=%d; CSQ_COL=\"%s\"; CSQ_RSSI=%d", csq, csq_per, csq_col, csq_rssi
            exit
        }
        
        END {
            if (!csq) print "CSQ=-1; CSQ_PER=0; CSQ_COL=\"black\"; CSQ_RSSI=0"
        }
    ')
}

# Get MCC or MNC 
function get_cops() {
	COPS=$(echo "$O" | awk -F[\"] '/^\+COPS:\s?.,[0-9]+/ {print $2}' | awk '{for(i=NF;i>=1;i--){w=tolower($i);if(!s[w]++)r=r?$i" "r:$i} print r}')	
}

# Get Registration data
function get_reg_data(){
	REGST=$(echo "$O" | awk -F',' '/\+CREG|\+CGREG|\+CEREG/ {print $2; exit}')
}

function generic_data(){
    MODE=$(echo "$O" | awk -F, '
        /^\+COPS/ {
            modes["2"] = "UMTS"
            modes["0"] = modes["3"] = "EDGE"
            modes["4"] = "HSDPA"
            modes["5"] = "HSUPA"
            modes["6"] = "HSPA"
            modes["7"] = "LTE"
	    modes["11"] = modes["12"] = "5GNR"
	    modes["10"] = modes["13"] = "LTE+NR"
            
            prefix = substr($4, 1, 2)
            print (prefix in modes ? modes[prefix] : "--")
        }')
}

# name device via mmcli utility
mmcli_name(){
        MMCLI=$(uci -q get modeminfo.@modeminfo[${s}].mmcli_name)
        if [ "$MMCLI" = "1" ]; then
                if [ -x /usr/bin/mmcli ]; then
                        MODEM=$(mmcli -L | awk '{print $1}' | awk -F [/] '{print $NF}')
                        for mm in $MODEM; do
                                MMCLIMEI=$(mmcli -m $mm -J | jsonfilter -e '@["modem"].*["imei"]')
                                IMEI=$(echo $IMEI | tr -d ' ')
                                if [ "$IMEI" = "$MMCLIMEI" ]; then
                                        MANUF=$(mmcli -m $mm -J | jsonfilter -e '@["modem"].*["manufacturer"]' | awk '{gsub("\r", ""); print $0}')
                                        MODEL=$(mmcli -m $mm -J | jsonfilter -e '@["modem"].*["model"]' | awk '{gsub("\r", ""); print $0}')
                                        if [ -n "$(echo "$MODEL" | grep "${MANUF}")" ]; then
                                                DEVICE="$MODEL"
                                        else
                                                DEVICE="$MANUF $MODEL"
                                        fi
                                fi
                        done
                fi
        fi
}

function get_data_in(){
	modem_family
	get_reg_data
	get_cops
	get_csq
	if [ -f "$RES/scripts/${FAMILY}" ]; then
		. $RES/scripts/$FAMILY
		modem_data
	else
		generic_data
	fi
	mmcli_name
}
