# qmi addon for luci-app-modeminfo
# require full version libqmi (need build in SDK)
# (c) 2020-2024 written by Konstantine Shevlakov (c) at <shevlakov@132lan.ru>

get_device_info() {
	DEVPORT=$(uci -q get modeminfo.@modeminfo[$s].device_qmi)
	DEVCTL=$(echo $DEVPORT | awk -F [\/] '{print $NF}')
	if [ -x /usr/bin/qmicli ]; then
		export QMICTL="qmicli -p -d $DEVPORT"
	else
 		logger -t "luci-app-modeminfo" "qmicli not found!"
		exit 1
	fi
	if [ $DEVPORT ]; then
		QPROXY=$(uci -q get modeminfo.@modeminfo[$s].qmi_proxy)
		if [ $QPROXY -eq 1 ]; then		   
			export QMICTL="qmicli -p -d $DEVPORT"
		else							  
			export QMICTL="qmicli -d $DEVPORT"   
		fi
	else
		QMI_DEVICE_FOUND=""
		for qmi in $(ls /dev/cdc-wdm* 2>/dev/null); do
			if [ -n "$qmi" ]; then
				if [ -x /usr/bin/qmicli ]; then
					export QMICTL="qmicli -p -d ${qmi}"
					QMI_DEVICE_FOUND="$qmi"
					break
				else
					logger -t "luci-app-modeminfo" "qmi-utils not found or installed!"
					exit 0
				fi
			fi
		done
		
		if [ -z "$QMI_DEVICE_FOUND" ]; then
			logger -t "luci-app-modeminfo" "Device is no QMI mode or not found!"
			exit 0
		else
			uci set modeminfo.@modeminfo[${s}].device_qmi="$QMI_DEVICE_FOUND"
			uci commit modeminfo
		fi
	fi
}


get_hardware_info() {
	mm=$(jsonfilter -s "$(mmcli -L -J)" -e "$['modem-list'][0]")
	mm_modem_json=$(mmcli -m "$mm" -J)
	mmi=$(jsonfilter -s "$mm_modem_json" -e "$['modem']['generic']['sim']")
	mmi="${mmi##*/}"
	mm_sim_json=$(mmcli -i "$mmi" -J)
	MODEL=$(jsonfilter -s "$mm_modem_json" -e "$['modem']['generic']['model']")
	MANUF=$(jsonfilter -s "$mm_modem_json" -e "$['modem']['generic']['manufacturer']")
	IMEI=$(jsonfilter -s "$mm_modem_json" -e "$['modem']['3gpp']['imei']")
	FW=$(jsonfilter -s "$mm_modem_json" -e "$['modem']['generic']['revision']" | tr '\n' ' ' | sed 's/  / /g')
	NUMBER=$(jsonfilter -s "$mm_modem_json" -e "$['modem']['generic']['own-numbers']" | tr -d '["] ' | sed -E 's/^(\+7|7|8)([0-9]{3})([0-9]{3})([0-9]{2})([0-9]{2})$/+7 (\2) \3-\4-\5/')
	ICCID=$(jsonfilter -s "$mm_sim_json" -e "$['sim']['properties']['iccid']" | sed 's/F$//')
	IMSI=$(jsonfilter -s "$mm_sim_json" -e "$['sim']['properties']['imsi']")
	if [ -n "$(echo "${MODEL}" | grep -Ei "${MANUF}")" ] || [ -n "$(echo "${MANUF}" | grep -Ei QUAL)" ]; then
		DEVICE="${MODEL}"
	else
		DEVICE="${MANUF} ${MODEL}"
	fi
	TX_RX_STATS=$($QMICTL --nas-get-tx-rx-info=lte)
	ANT0POWER=$(echo "$TX_RX_STATS" | awk '/TX:/ {exit} /Power:/' | awk 'NR==1 {print $2}' | tr -d "'")
	ANT0ECIO=$(echo "$TX_RX_STATS" | grep ECIO | awk 'NR==1 {print $2}' | tr -d "'")
	ANT0RSRP=$(echo "$TX_RX_STATS" | grep RSRP | awk 'NR==1 {print $2}' | tr -d "'")
	ANT1POWER=$(echo "$TX_RX_STATS" | awk '/TX:/ {exit} /Power:/' | awk 'NR==2 {print $2}' | tr -d "'")
	ANT1ECIO=$(echo "$TX_RX_STATS" | grep ECIO | awk 'NR==2 {print $2}' | tr -d "'")
	ANT1RSRP=$(echo "$TX_RX_STATS" | grep RSRP | awk 'NR==2 {print $2}' | tr -d "'")
	ANT2POWER=$(echo "$TX_RX_STATS" | awk '/TX:/ {exit} /Power:/' | awk 'NR==3 {print $2}' | tr -d "'")
	ANT2ECIO=$(echo "$TX_RX_STATS" | grep ECIO | awk 'NR==3 {print $2}' | tr -d "'")
	ANT2RSRP=$(echo "$TX_RX_STATS" | grep RSRP | awk 'NR==3 {print $2}' | tr -d "'")
	ANT3POWER=$(echo "$TX_RX_STATS" | awk '/TX:/ {exit} /Power:/' | awk 'NR==4 {print $2}' | tr -d "'")
	ANT3ECIO=$(echo "$TX_RX_STATS" | grep ECIO | awk 'NR==4 {print $2}' | tr -d "'")
	ANT3RSRP=$(echo "$TX_RX_STATS" | grep RSRP | awk 'NR==4 {print $2}' | tr -d "'")
	ANT4POWER=$(echo "$TX_RX_STATS" | awk '/TX:/ {exit} /Power:/' | awk 'NR==5 {print $2}' | tr -d "'")
	ANT4ECIO=$(echo "$TX_RX_STATS" | grep ECIO | awk 'NR==5 {print $2}' | tr -d "'")
	ANT4RSRP=$(echo "$TX_RX_STATS" | grep RSRP | awk 'NR==5 {print $2}' | tr -d "'")
	ANT5POWER=$(echo "$TX_RX_STATS" | awk '/TX:/ {exit} /Power:/' | awk 'NR==6 {print $2}' | tr -d "'")
	ANT5ECIO=$(echo "$TX_RX_STATS" | grep ECIO | awk 'NR==6 {print $2}' | tr -d "'")
	ANT5RSRP=$(echo "$TX_RX_STATS" | grep RSRP | awk 'NR==6 {print $2}' | tr -d "'")
	ANT6POWER=$(echo "$TX_RX_STATS" | awk '/TX:/ {exit} /Power:/' | awk 'NR==7 {print $2}' | tr -d "'")
	ANT6ECIO=$(echo "$TX_RX_STATS" | grep ECIO | awk 'NR==7 {print $2}' | tr -d "'")
	ANT6RSRP=$(echo "$TX_RX_STATS" | grep RSRP | awk 'NR==7 {print $2}' | tr -d "'")
	ANT7POWER=$(echo "$TX_RX_STATS" | awk '/TX:/ {exit} /Power:/' | awk 'NR==8 {print $2}' | tr -d "'")
	ANT7ECIO=$(echo "$TX_RX_STATS" | grep ECIO | awk 'NR==8 {print $2}' | tr -d "'")
	ANT7RSRP=$(echo "$TX_RX_STATS" | grep RSRP | awk 'NR==8 {print $2}' | tr -d "'")
	MANUF_LC="$(echo "$MANUF" | tr 'A-Z' 'a-z')"
	MODEL_LC="$(echo "$MODEL" | tr 'A-Z' 'a-z')"
	case "$MANUF_LC" in
		dell*|telit*|thales*)
			case "$MODEL_LC" in
				fn990a28*)
					CHIPTEMP=$(sms_tool -d $(uci get atinout.general.atc_port) at "AT#TEMPSENS=2" | grep TSENS | awk '{print $2}' | sed 's/[^0-9]*//g')
					;;
				*ln940*)
					CHIPTEMP=$(sms_tool -d $(uci get atinout.general.atc_port) at "AT+TEMP" | grep "tsens_tz_sensor0" | awk -F':' '{print $2}' | sed 's/[^0-9]//g')
					;;
				*)
					CHIPTEMP=$(sms_tool -d $(uci get atinout.general.atc_port) at "AT^TEMP?" | grep TSENS | awk '{print $2}' | sed 's/[^0-9]*//g')
					[ -z "$CHIPTEMP" ] && CHIPTEMP=$(sms_tool -d $(uci get atinout.general.atc_port) at "AT+TEMP?" | grep "xo_therm_buf" | awk -F':' '{print $2}' | sed 's/[^0-9]//g')
					;;
			esac
			;;
		microsoft*|android*)
			if echo "$FW" | grep -qiE 't[0-9]{2}w[0-9]{3}'; then
				CHIPTEMP=$(sms_tool -d $(uci get atinout.general.atc_port) at "AT^TEMP?" | grep TSENS | awk '{print $2}' | sed 's/[^0-9]*//g')
			fi
			;;
		quectel*)
			AT_OUT=$(sms_tool -d $(uci get atinout.general.atc_port) at "AT+QTEMP")
			CHIPTEMP=$(echo "$AT_OUT" | grep TSENS | head -n 1 | awk '{print $2}' | sed 's/[^0-9]*//g')
			[ -z "$CHIPTEMP" ] && CHIPTEMP=$(echo "$AT_OUT" | awk -F'"' '/mdm-case-therm-adc/ {print $4}')
			[ -z "$CHIPTEMP" ] && CHIPTEMP=$(echo "$AT_OUT" | awk -F': ' '/^\+QTEMP:/ {split($2, a, ","); print a[1]}')
			;;
		qualcomm*)
			case "$MODEL_LC" in
				*simcom*)
					CHIPTEMP=$(sms_tool -d $(uci get atinout.general.atc_port) at "AT+CPMUTEMP" | grep CPMUTEMP | awk '{print $2}' | sed 's/[^0-9]*//g')
					;;
				*)
					CHIPTEMP=$(sms_tool -d $(uci get atinout.general.atc_port) at "AT+TEMP" | grep "tsens_tz_sensor0" | awk -F':' '{print $2}' | sed 's/[^0-9]//g')
					;;
			esac
			;;
	esac
}


get_lte_bw() {
	case $BWDx in
		3) BWDL=1 ;;
		5) BWDL=2 ;;
		10) BWDL=3 ;;
		15) BWDL=4 ;;
		20) BWDL=5 ;;
	esac
}

get_signal_info() {
	NETWORK=`$QMICTL --nas-get-home-network | awk -F [:] '/MCC|MNC|Description/{gsub("'\''|^ ", "");print $2}'`
	COPS_MCC=$(echo ${NETWORK} |awk '{print $1}')
	COPS_MNC_RAW=$(echo ${NETWORK} |awk '{print $2}')
	if [ $COPS_MNC_RAW -lt 10 ]; then
		COPS_MNC=00${COPS_MNC_RAW}
	elif [ $COPS_MNC_RAW -lt 100 ]; then
		COPS_MNC=0${COPS_MNC_RAW}
	else
		COPS_MNC=$COPS_MNC_RAW
	fi
	COPS="$(echo "${NETWORK}" |tail -1)"
	PLMN="${COPS_MCC}${COPS_MNC}"
	SIGNAL=$($QMICTL --nas-get-signal-info)
	MODE=$(echo "$SIGNAL" | awk 'NR ==2{gsub("\:", ""); print $1}')
	STRENGTH=$(echo "$SIGNAL" | awk '/RSSI|RSRQ|RSRP|SNR|ECIO/{gsub("'\''",""); print $2}')
	SERVING=$($QMICTL --nas-get-serving-system)
	RFBAND=$($QMICTL --nas-get-rf-band-info)
	if  [ $MODE == "LTE" ]; then
		MIMO=$($QMICTL --nas-get-tx-rx-info=lte | grep 'RX Chain' | wc -l)
		LACTAC=$(echo "$SERVING" | awk -F [:] '/tracking area code:|3GPP cell ID:/{gsub("'\''",""); print $2}')
		LAC_NUM=$(echo $LACTAC | awk '{print $2}')
		CID_NUM=$(echo $LACTAC | awk '{print $1}')
		CID=$(echo $CID_NUM | awk '{printf "%x\n", $1}' |awk '{print toupper($1)}')
		LAC=$(echo $LAC_NUM | awk '{printf "%x\n", $1}' |awk '{print toupper($1)}')
		CSQ_RSSI=$(echo ${STRENGTH} | awk '{print $1}')
		RSRQ=$(echo ${STRENGTH} | awk '{print $2}')
		RSRP=$(echo ${STRENGTH} | awk '{print $3}')
		SINR=$(echo ${STRENGTH} | awk '{printf "%.0f\n", $4}')
		ENBx=$(echo $CID | sed -e 's/..$//')
		ENBID=$(printf %d 0x$ENBx)
		CELL=$(printf %d 0x${CID: -2})
		CELL_LOCATION_INFO=$($QMICTL --nas-get-cell-location-info)
		PCI=$(echo "$CELL_LOCATION_INFO" | awk -F [:] '/Serving Cell ID:/{gsub("'\''",""); print $2}')
		local fix_t77=0
		case "$(echo "$DEVICE" | tr 'A-Z' 'a-z')" in
			*android*|*dell*|*ln960*|*dw5821e*)
				if echo "$FW" | grep -qi 't77w968'; then
					fix_t77=1
				fi
				;;
		esac

		LTE_O=$($QMICTL --nas-get-lte-cphy-ca-info 2>/dev/null)
		eval $(echo "$LTE_O" | awk -v fix_t77="$fix_t77" '
			function get_band_mhz(b) {
				if (b == "1") return "2100"
				if (b == "3") return "1800"
				if (b == "7") return "2600"
				if (b == "8") return "900"
				if (b == "20") return "800"
				if (b == "38") return "2600"
				if (b == "40") return "2300"
				return "0"
			}
			function process_cell(is_sec) {
				if (rx_chan != "0" && rx_chan != "") {
					b_num = band; gsub(/[^0-9]/, "", b_num);
					if (fix_t77 == 1) {
						b_num = b_num - 1;
					}
					mhz = get_band_mhz(b_num);
					st = ""; if (state ~ /deactivated/) st = " (deactivated)";
					if (is_sec) {
						if (state !~ /deconfigured/) {
							ca_count++;
							if (bw != "" && bw != "unknown" && bw != "0") bwc = bwc "+" bw;
							if (band != "") bands = bands " " b_num;
							bw_str = ""; if (bw != "" && bw != "unknown" && bw != "0") bw_str = " @" bw " MHz";
							str = "SCC" ca_count " B" b_num " (" mhz " MHz)" bw_str " | " pci " " rx_chan st;
							if (scc_str != "") scc_str = scc_str "<br>" str;
							else scc_str = str;
						}
					} else {
						bw_str = ""; if (bw != "" && bw != "unknown" && bw != "0") bw_str = " @" bw " MHz";
						pcc_str = "PCC B" b_num " (" mhz " MHz)" bw_str " | " pci " " rx_chan;
					}
				}
			}
			BEGIN { ca_count=0; bwc=""; bands=""; pcc_str=""; scc_str=""; cell_type="" }
			/^Secondary Cell/ {
				if (cell_type != "") process_cell(cell_type == "sec");
				cell_type = "sec"; state = ""; rx_chan = ""; bw = ""; band = ""; pci = ""; next
			}
			/^Primary Cell/ {
				if (cell_type != "") process_cell(cell_type == "sec");
				cell_type = "pri"; state = ""; rx_chan = ""; bw = ""; band = ""; pci = ""; next
			}
			cell_type != "" && /State:/ { val=$NF; gsub(/[\047]/, "", val); state = val }
			cell_type != "" && /RX Channel:/ { val=$NF; gsub(/[^0-9]/, "", val); rx_chan = val }
			cell_type != "" && /DL Bandwidth:/ { val=$NF; gsub(/[^0-9.]/, "", val); bw = val }
			cell_type != "" && /LTE Band:/ { val=$NF; gsub(/[\047]/, "", val); band = val }
			cell_type != "" && /Physical Cell ID:/ { val=$NF; gsub(/[^0-9]/, "", val); pci = val }
			END {
				if (cell_type != "") process_cell(cell_type == "sec");
				print "LTE_CA=" ca_count ";"
				print "BWC=\"" bwc "\";"
				print "CA_BANDS=\"" bands "\";"
				print "PCC_STR=\"" pcc_str "\";"
				print "SCC_STR=\"" scc_str "\";"
			}
		')
		BWDx=$(echo "$LTE_O" | awk -F ":" '/^Primary Cell/{p=1} /^Secondary Cell/{p=0} p&&/DL Bandwidth/{gsub("'\''| ", "", $2); print $2; exit}')
		if [ -z "$BWDx" ]; then
			BWDx=$(sms_tool -d $(uci get atinout.general.atc_port) at "AT^CA_INFO?" | sed -n 's/.*Band_width is \([0-9.]*\).*/\1/p' | awk '{print int($1)}')
		fi
		get_lte_bw
		if [ $LTE_CA -ge 1 ]; then
			BWCA=$(($BWDx$BWC))
			BANDCH=$(echo "$LTE_O" | awk -F ":" '/^Primary Cell/{p=1} /^Secondary Cell/{p=0} p&&/RX Channel/{gsub("'\''| ", "", $2); print $2; exit}')
			CA="$CA_BANDS"
			for cc in $CA; do
				SCC=$SCC+$cc
			done
		else
			BANDCH=$(echo "$RFBAND" |  awk -F [:] '/Active Channel:/{gsub("'\''",""); print $2}' | head -1)
			if [ "x" == "x$BWDx" ]; then
				BWDx=$(echo "$RFBAND" | awk -F [:] '/Bandwidth:/{gsub("'\''| ",""); print $2}' | tail -1)
				get_lte_bw
			fi
		fi	
		EARFCN=$BANDCH
	else
		MIMO=$($QMICTL --nas-get-tx-rx-info=umts | grep 'RX Chain' | wc -l)
		case $MIMO in
			0) MIMO=$($QMICTL --nas-get-tx-rx-info=gsm | grep 'RX Chain' | wc -l) ;;
		esac
		LACTAC=$(echo "$SERVING" | awk -F [:] '/3GPP location area code:|3GPP cell ID:/{gsub("'\''",""); print $2}')
		LAC_NUM=$(echo $LACTAC | awk '{print $1}')
		CID_NUM=$(echo $LACTAC | awk '{print $2}')
		LAC=$(echo $LAC_NUM | awk '{printf "%x\n", $1}' |awk '{print toupper($1)}')
		CID=$(echo $CID_NUM | awk '{printf "%x\n", $1}' |awk '{print toupper($1)}')
		CSQ_RSSI=$(echo ${STRENGTH} | awk '{print $1}')
		if [ $(echo  ${STRENGTH} | awk '{print$2}') ]; then
			SINR=$(echo ${STRENGTH} | awk '{printf "%.0f\n", $2}')
		fi
		BANDCH=$(echo "$RFBAND" |  awk -F [:] '/Active Channel:/{gsub("'\''| ",""); print $2}')
		EARFCN=$(echo $BANDCH | awk '{print $2}')
	fi
	CSQ_PER=$(echo $CSQ_RSSI |awk '{printf "%d\n", (100*(1-(-50 - $1)/(-50 - -120)))}')
	[ $CSQ_RSSI -ge -110 ] && CSQ_COL="black"
	[ $CSQ_RSSI -ge -105 ] && CSQ_COL="red"
	[ $CSQ_RSSI -ge -95 ] && CSQ_COL="orange"
	[ $CSQ_RSSI -ge -75 ] && CSQ_COL="green"
	if [ $CSQ_PER -gt 100 ]; then
		CSQ_PER=100
	elif [ $CSQ_PER -lt 0 ]; then
		CSQ_PER=0
	fi
	EARFCN=$BANDCH
	TA=$(echo "$CELL_LOCATION_INFO" | awk -F"'" '/LTE Timing Advance/ {gsub(" us","",$2); print $2}')
	DISTANCE=$(echo "$CELL_LOCATION_INFO" | awk '/LTE Timing Advance:/{gsub("\047",""); printf "%.2f\n", (299792458*($4*10^-6)/1000)/2}')
	REG=$(echo "$SERVING" | awk -F [:] '/Registration state:/{print $2}' | sed "s/'//g" | awk '{print $1}')
	case $REG in
		registered)
			REGST=1
		;;
		registration-denied)
			REGST=3
		;;
	esac
}


#get_device
function get_data_in() {
	get_hardware_info >/dev/null 2>&1
	get_signal_info >/dev/null 2>&1
}

get_hwinfo() {
	continue
}
