#!/bin/sh
. /lib/functions/procd.sh
 
MODCNT=6

ROOTER=/usr/lib/rooter
ROOTER_LINK="/tmp/links"

modeswitch="/usr/bin/usb_modeswitch"

log() {
	modlog "usb-modeswitch $CURRMODEM" "$@"
}

sanitize() {
	sed -e 's/[[:space:]]\+$//; s/[[:space:]]\+/_/g' "$@"
}

find_usb_attrs() {
	local usb_dir="/sys$DEVPATH"
	[ -f "$usb_dir/idVendor" ] || usb_dir="${usb_dir%/*}"

	uVid=$(cat "$usb_dir/idVendor")
	uPid=$(cat "$usb_dir/idProduct")
	uMa=$(sanitize "$usb_dir/manufacturer")
	uPr=$(sanitize "$usb_dir/product")
	uSe=$(sanitize "$usb_dir/serial")
}

display_top() {
	log "*****************************************************************"
	log "*"
}

display_bottom() {
	log "*****************************************************************"
}


display() {
	local line1=$1
	log "* $line1"
	log "*"
}

#
# Save Interface variables
#
save_variables() {
	echo 'MODSTART="'"$MODSTART"'"' > /tmp/variable.file
	echo 'WWAN="'"$WWAN"'"' >> /tmp/variable.file
	echo 'USBN="'"$USBN"'"' >> /tmp/variable.file
	echo 'ETHN="'"$ETHN"'"' >> /tmp/variable.file
	echo 'WDMN="'"$WDMN"'"' >> /tmp/variable.file
	echo 'BASEPORT="'"$BASEPORT"'"' >> /tmp/variable.file
}
#
# delay until ROOter Initialization done
#
bootdelay() {
	if [ ! -f /tmp/bootend.file ]; then
		log "Delay for boot up"
		sleep 1
		while [ ! -f /tmp/bootend.file ]; do
			sleep 1
		done
		sleep 1
	fi
}

#
# return modem number based on port number
# 0 is not found
#
find_device() {
	DEVN=$1
	COUNTER=1
	while [ $COUNTER -le $MODCNT ]; do
		EMPTY=$(uci get modem.modem$COUNTER.empty)
		if [ $EMPTY -eq 0 ]; then
			DEVS=$(uci get modem.modem$COUNTER.device)
			if [ $DEVN = $DEVS ]; then
				retresult=$COUNTER
				return
			fi
		fi
		let COUNTER=COUNTER+1
	done
	retresult=0
}

find_empty() {
	COUNTER=1
	while [ $COUNTER -le $MODCNT ]; do
		EMPTY=$(uci get modem.modem$COUNTER.empty)
		if [ $EMPTY -eq 1 ]; then
			remresult=$COUNTER
			return
		fi
		let COUNTER=COUNTER+1
	done
	remresult=0
}

#
# check if all modems are inactive or empty
# delete all if nothing active
#
check_all_empty() {
	COUNTER=1
	while [ $COUNTER -le $MODCNT ]; do
		EMPTY=$(uci get modem.modem$COUNTER.empty)
		if [ $EMPTY -eq 0 ]; then
			ACTIVE=$(uci get modem.modem$COUNTER.active)
			if [ $ACTIVE -eq 1 ]; then
				return
			fi
		fi
		let COUNTER=COUNTER+1
	done
	COUNTER=1
	while [ $COUNTER -le $MODCNT ]; do
		uci delete modem.modem$COUNTER
		uci set modem.modem$COUNTER=modem
		uci set modem.modem$COUNTER.empty=1
		let COUNTER=COUNTER+1
	done
	uci set modem.general.modemnum=1
	uci commit modem
	MODSTART=1
	WWAN=0
	USBN=0
	ETHN=1
	WDMN=0
	BASEPORT=0
	if
		ifconfig eth1
	then
		if [ -e "/sys/class/net/eth1/device/bInterfaceProtocol" ]; then
			ETHN=1
		else
			ETHN=2
		fi
	fi
	save_variables
	display_top; display "No Modems present"; display_bottom
}

change_bconf() {
	local devname=$1
	local conf=$2
	local mode=$3
	local unconf=0
	log "Switching Modem at $DEVICENAME to $mode by selecting Cfg# $bestcfg"
	echo $unconf >/sys/bus/usb/devices/$devname/bConfigurationValue
	sleep 1
	echo $conf >/sys/bus/usb/devices/$devname/bConfigurationValue
}


#
# Add Modem and connect
#
#log "$ACTION"
if [ "$ACTION" = add ]; then
	bootdelay
	if [ -e /tmp/gotpcie ]; then
		find_usb_attrs
		if [ "$uPr" = "USB_Storage" ]; then
			exit 0
		fi
		exit 0
		$ROOTER/proto.sh $uVid $uPid $DEVICENAME 0
		source /tmp/proto
		rm -f /tmp/proto
		if [ $retval = 11 ]; then
			exit 0
		fi
	fi
	
	find_usb_attrs
	
		
	if [ $uVid = 10c4 -a $uPid = ea60 ]; then
		log "Ignoring CP2104 USB to UART Bridge Controller"
		exit 0
	fi

#
# Ignore Ethernet adapters
#
	if [ $uVid = 13b1 -a $uPid = 0041 ]; then
		exit 0
	elif [ $uVid = 2357 -a $uPid = 0601 ]; then
		exit 0
	elif [ $uVid = 1782 -a $uPid = 4d00 ]; then
		exit 0
	elif [ $uVid = 0b95 -a $uPid = 772b ]; then
		exit 0
	elif [ $uVid = 0b95 -a $uPid = 1790 ]; then
		exit 0
	elif [ $uVid = 0bda -a $uPid = 8152 ]; then
		exit 0
	elif [ $uVid = 0e8d -a $uPid = 2000 ]; then
		exit 0
	elif [ $uVid = 18d1 -a $uPid = 4ee7 ]; then
		exit 0
	elif [ $uVid = 2109 -a $uPid = 8822 ]; then
		exit 0
	elif [ $uVid = 248a -a $uPid = 8379 ]; then
		exit 0
	fi
	
	CNTR=0
	while [ -e /tmp/modgone ]; do
		sleep 1
		CNTR=`expr $CNTR + 1`
		if [ $CNTR -gt 10 ]; then
			rm -f /tmp/modgone
			break
		fi
	done

	if echo $DEVICENAME | grep -q ":" ; then
		exit 0
	fi

	if [ -z $uMa ]; then
		log "Ignoring Unnamed Hub"
		exit 0
	fi

	UPR=${uPr}
	CT=`echo $UPR | tr '[A-Z]' '[a-z]'`
	if echo $CT | grep -q "hub" ; then
		log "Ignoring Named Hub"
		exit 0
	fi

		if [ $uVid = 1d6b ]; then
		log "Ignoring Linux Hub"
		exit 0
	fi


	DELAY=1
	if [ -f /tmp/usbwait ]; then
		log "Delay for previous modem $DEVICENAME"
		while [ -f /tmp/usbwait ]; do
			sleep 1
			let DELAY=$DELAY+1
			if [ $DELAY -gt 35 ]; then
				break
			fi
		done
	fi
	echo "1" > /tmp/usbwait

	bNumConfs=$(cat /sys/bus/usb/devices/$DEVICENAME/bNumConfigurations)
	bNumIfs=$(cat /sys/bus/usb/devices/$DEVICENAME/bNumInterfaces)

	# Uncomment the next line to ignore USB-Serial adapters and similar single-port devices
	# if [ $bNumConfs = 1 -a $bNumIfs = 1 ] && exit 0		

	$ROOTER/proto.sh $uVid $uPid $DEVICENAME 0
	source /tmp/proto
	rm -f /tmp/proto

	if [ -e /etc/config/mjpg-streamer ]; then
		if [ $retval -eq 99 ]; then
			log "Start MJPEG Streamer $DEVICENAME"
			/etc/init.d/mjpg-streamer start
			uci delete mjpg-streamer.camera
			uci set mjpg-streamer.camera=mjpg-stream
			uci set mjpg-streamer.camera.idv=$DEVICENAME
			uci commit mjpg-streamer
			exit 0
		fi
	fi
	if [ -e /etc/config/p910nd ]; then
		if [ $retval -eq 98 ]; then
			# Check if lp device is plugged in and p910nd is not already started
			log "USB Printer device plugged in, starting p910nd"
			/etc/init.d/p910nd start
			uci delete p910nd.printer
			uci set p910nd.printer=printer
			uci set p910nd.printer.idv=$DEVICENAME
			uci commit p910nd
			exit 0
		fi
	fi
	if [ $retval -eq 97 ]; then
		if grep "$uVid:$uPid" /etc/usb-mode.json > /dev/null ; then
			log "Modem found"
		else
			log "Found USB Storage"
			rm -f /tmp/usbwait
			exit 0
		fi
	fi


	
	source /tmp/variable.file
	source /tmp/modcnt
	MODCNT=$MODCNTX

	reinsert=0
	find_device $DEVICENAME
	find_empty
	if [ "$remresult" = "0" ]; then
		log "Exceeded Maximum Number of Modems"
		exit 0
	fi
	log "CURRMODEM $remresult"
 
	log "Add : $DEVICENAME: Manufacturer=${uMa:-?} Product=${uPr:-?} Serial=${uSe:-?} $uVid $uPid"

	if [ $reinsert = 0 ]; then
		CURRMODEM=$remresult
	fi
	
	if [ -e /tmp/gotpcie1 ]; then
		gpc=$(cat /tmp/gotpcie1)
		if [ "$gpc" = $CURRMODEM ]; then
			uci set modem.modem$CURRMODEM.empty=1
			uci commit modem
			log "Exit from PCie"
			exit 0
		fi
	fi

	FILEN=$uVid:$uPid
	display_top; display "Start of Modem Detection and Connection Information"
	display "Product=${uPr:-?} $uVid $uPid"; display_bottom
	cat /sys/kernel/debug/usb/devices > /tmp/prembim
	lua $ROOTER/mbimfind.lua $uVid $uPid
	retval=$?
	rm -f /tmp/prembim
	if [ ! -e /sbin/umbim ]; then
		retval=0
	fi

	while : ; do
		bConfig=$(cat /sys/bus/usb/devices/$DEVICENAME/bConfigurationValue)
		if [ -n "$bConfig" -a -n "$bNumConfs" ]; then
			log "Found Modem at $DEVICENAME in Cfg#= $bConfig from $bNumConfs available"
			break
		else
			sleep 1
		fi
	done

	FORCEQMI='03f0:0857 1bc7:1900'
	if echo $FORCEQMI | grep -q -i "$FILEN"; then
		bestcfg=1
		if [ $bConfig -ne $bestcfg ]; then
			change_bconf $DEVICENAME $bestcfg QMI
		fi
	else
		if [ $retval -ne 0 ]; then
			display_top; display "Found MBIM Modem at $DEVICENAME with Config of $retval"; display_bottom
			if [ $FILEN = "12d1:15c1" ]; then
				bestcfg=2
				if [ $bConfig -ne $bestcfg ]; then
					change_bconf $DEVICENAME $bestcfg ECM
				fi
			elif [ $FILEN = "413c:81d7" -o $FILEN = "05c6:9025" ]; then
				bestcfg=1
				case $bNumConfs in
				"3" )
					change_bconf $DEVICENAME $bestcfg QMI
					;;
				"2" )
					if [ $bNumIfs -lt 4 ]; then
						change_bconf $DEVICENAME $bestcfg QMI
					fi
					;;
				esac
			elif [ $FILEN = "03f0:9d1d" -a $bNumConfs -eq 3 ]; then
				bestcfg=1
				change_bconf $DEVICENAME $bestcfg QMI
			else
				if [ $bConfig -ne $retval ]; then
					change_bconf $DEVICENAME $retval MBIM
				fi
			fi
		else
			if grep "$FILEN" /etc/usb-mode.json > /dev/null ; then
				procd_open_service "usbmode"
				procd_open_instance
				procd_set_param command "/sbin/usbmode" -s
				procd_close_instance
				procd_close_service
			else
				display_top; display "Device at $DEVICENAME does not have a switch data file"; display_bottom
			fi
		fi
	fi
	echo "1" > /tmp/usbwait
	sleep 10
	usb_dir="/sys$DEVPATH"
	idV="$(sanitize "$usb_dir/idVendor")"
	idP="$(sanitize "$usb_dir/idProduct")"
	display_top; display "Modem at $DEVICENAME switched to : $idV:$idP"; display_bottom

	if [ $idV = 2357 -a $idP = 9000 ]; then
		sleep 10
	fi

	#cat /sys/kernel/debug/usb/devices > /tmp/wdrv
	#lua $ROOTER/protofind.lua $idV $idP 1
	$ROOTER/proto.sh $uVid $uPid $DEVICENAME 1
	source /tmp/proto
	rm -f /tmp/proto
	#retval=$?
	if [ $idV = 8087 -a $idP = 095a ]; then
		retval=28
	fi
	if [ $idV = 2cb7 -a $idP = 000b ]; then
		retval=28
	fi
	if [ $idV != 12d1 -a $retval = 24 ]; then
		retval=5
	fi
	display_top; display "ProtoFind returns : $retval"; display_bottom
	rm -f /tmp/wdrv

	if [ $reinsert = 0 ]; then
		BASEP=$BASEPORT
		if [ -f /tmp/drv ]; then
			source /tmp/drv
			BASEPORT=`expr $PORTN + $BASEPORT`
		fi
	fi
	rm -f /tmp/drv

	if [ $retval -ne 0 ]; then
		log "Found Modem $CURRMODEM"
		if [ $reinsert = 0 ]; then
			if -e "/tmp/gotpcie1" ]; then
				gpc=$(cat /tmp/gotpcie1)
				if [ "$gpc" = $CURRMODEM ]; then
					exit 0
				fi
			fi
			uci set modem.modem$CURRMODEM.empty=0
			uci set modem.modem$CURRMODEM.uVid=$uVid
			uci set modem.modem$CURRMODEM.uPid=$uPid
			uci set modem.modem$CURRMODEM.idV=$idV
			uci set modem.modem$CURRMODEM.idP=$idP
			uci set modem.modem$CURRMODEM.device=$DEVICENAME
			uci set modem.modem$CURRMODEM.baseport=$BASEP
			uci set modem.modem$CURRMODEM.maxport=$BASEPORT
			uci set modem.modem$CURRMODEM.proto=$retval
			uci set modem.modem$CURRMODEM.maxcontrol=/sys$DEVPATH/descriptors
			find_usb_attrs
			uci set modem.modem$CURRMODEM.manuf=$uMa
			uci set modem.modem$CURRMODEM.model=$uPr
			uci set modem.modem$CURRMODEM.serial=$uSe
			uci set modem.modem$CURRMODEM.celltype="-"
		fi
		uci set modem.modem$CURRMODEM.active=1
		uci set modem.modem$CURRMODEM.connected=0
		uci commit modem
		if [ -e $ROOTER/modem-led.sh ]; then
			$ROOTER/modem-led.sh $CURRMODEM 1
		fi
	fi

#	if [ $reinsert = 0 -a $retval != 0 ]; then
#		MODSTART=`expr $MODSTART + 1`
#		save_variables
#	fi
	PID=$(ps |grep "chkconn.sh" | grep -v grep |head -n 1 | awk '{print $1}')
	kill -9 $PID

	if [ -e /etc/config/wizard]; then
		uci set wizard.basic.detect="0"
		uci commit wizard
	fi
	rm -f /tmp/usbwait
#
# Handle specific modem models
#
	case $retval in
	"0" )
		#
		# ubox GPS module
		#
		if [ $idV = 1546 ]; then
			if echo $uPr | grep -q "GPS"; then
				SYMLINK="gps0"
				BASEX=`expr 1 + $BASEP`
				ln -s /dev/ttyUSB$BASEX /dev/${SYMLINK}
				display_top ; display "Hotplug Symlink from /dev/ttyUSB$BASEX to /dev/${SYMLINK} created"
				display_bottom
			fi
		fi
		rm -f /tmp/usbwait
		exit 0
		;;
	"1" )
		log "Connecting a Sierra Modem"
		ln -s $ROOTER/connect/create_connect.sh $ROOTER_LINK/create_proto$CURRMODEM
		$ROOTER_LINK/create_proto$CURRMODEM $CURRMODEM &
		;;
	"2" )
		log "Connecting a QMI Modem"
		ln -s $ROOTER/connect/create_connect.sh $ROOTER_LINK/create_proto$CURRMODEM
		$ROOTER_LINK/create_proto$CURRMODEM $CURRMODEM &
		;;
	"3" )
		log "Connecting a MBIM Modem"
		ln -s $ROOTER/connect/create_connect.sh $ROOTER_LINK/create_proto$CURRMODEM
		$ROOTER_LINK/create_proto$CURRMODEM $CURRMODEM &
		;;
	"6"|"4"|"7"|"24"|"26"|"27" )
		log "Connecting a Huawei NCM Modem"
		ln -s $ROOTER/connect/create_connect.sh $ROOTER_LINK/create_proto$CURRMODEM
		$ROOTER_LINK/create_proto$CURRMODEM $CURRMODEM &
		;;
	"28" )
		log "Connecting a Fibocom NCM Modem"
		ln -s $ROOTER/connect/create_connect.sh $ROOTER_LINK/create_proto$CURRMODEM
		$ROOTER_LINK/create_proto$CURRMODEM $CURRMODEM &
		;;
	"5" )
		log "Connecting a Hostless Modem or Phone"
		ln -s $ROOTER/connect/create_hostless.sh $ROOTER_LINK/create_proto$CURRMODEM
		$ROOTER_LINK/create_proto$CURRMODEM $CURRMODEM &
		;;
	"10"|"11"|"12"|"13"|"14"|"15"|"16" )
		if [ "$retval" = "11" ]; then
			if [ -e /dev/wwan0mbim0 ]; then
				log "Connecting a MHI Modem"
				uci set modem.modem$CURRMODEM.proto=91
				ln -s $ROOTER/mhi/create_mhi.sh $ROOTER_LINK/create_proto$CURRMODEM
			else
				echo "1" > /sys/bus/pci/rescan
				log "Rescan"
				sleep 2
				if [ -e /dev/wwan0mbim0 ]; then
					log "Connecting a MHI Modem"
					uci set modem.modem$CURRMODEM.proto=91
					ln -s $ROOTER/mhi/create_mhi.sh $ROOTER_LINK/create_proto$CURRMODEM
				else
					log "Connecting a PPP Modem"
					ln -s $ROOTER/ppp/create_ppp.sh $ROOTER_LINK/create_proto$CURRMODEM
				fi
			fi
			$ROOTER_LINK/create_proto$CURRMODEM $CURRMODEM
		else
			log "Connecting a PPP Modem"
			ln -s $ROOTER/ppp/create_ppp.sh $ROOTER_LINK/create_proto$CURRMODEM
			$ROOTER_LINK/create_proto$CURRMODEM $CURRMODEM
		fi
		;;
	"9" )
		log "Connecting an iPhone"
		ln -s $ROOTER/connect/create_iphone.sh $ROOTER_LINK/create_proto$CURRMODEM
		$ROOTER_LINK/create_proto$CURRMODEM $CURRMODEM
		;;
	esac

fi

#
# Remove Modem
#
if [ "$ACTION" = remove ]; then
	find_usb_attrs

	if echo $DEVICENAME | grep -q ":" ; then
		exit 0
	fi
	log "Remove $DEVICENAME"
	find_device $DEVICENAME
	if [ $retresult -gt 0 ]; then
		IDP=$(uci get modem.modem$retresult.idP)
		IDV=$(uci get modem.modem$retresult.idV)
		#if [ $uVid = $IDV ]; then
		if [ 0 -eq 1 ]; then
			exit 0
		else
			INTER=$(uci get modem.modem$retresult.inter)
			if [ -z $INTER ]; then
				INTER=$retresult
			fi
			if [ -e $ROOTER/modem-led.sh ]; then
				$ROOTER/modem-led.sh $retresult 0
			fi
			uci set modem.modem$retresult.active=0
			uci set modem.modem$retresult.empty=1
			uci set modem.modem$retresult.connected=0
			uci commit modem
			if [ -e /etc/config/mwan3 ]; then
				ENB=$(uci get mwan3.wan$retresult.enabled)
				if [ ! -z $ENB ]; then
					uci set mwan3.wan$INTER.enabled=0
					uci commit mwan3
				fi
			fi
			SMS=$(uci get modem.modem$CURRMODEM.sms)
			if [ $SMS = 1 ]; then
				if [ -e /usr/lib/sms/stopsms ]; then
					/usr/lib/sms/stopsms $CURRMODEM
				fi
			fi
			ifdown wan$INTER
			uci delete network.wan$INTER
			uci set network.wan$INTER=interface
			uci set network.wan$INTER.proto=dhcp
			ifname1="ifname"
			if [ -e /etc/newstyle ]; then
				ifname1="device"
			fi
			uci set network.wan$INTER.${ifname1}=" "
			uci set network.wan$INTER.metric=$INTER"0"
			
			uci -q delete network.wan$INTER"_6"
			uci set network.wan$INTER'_6'=interface
			uci set network.wan$INTER'_6'.proto=none
			uci set network.wan$INTER'_6'.${ifname1}="@wan$COUNTER"
			uci set network.wan$INTER'_6'.metric=$INTER"0"
		
			uci commit network
			/etc/init.d/network reload
			ifdown wan$INTER
			PID=$(ps |grep "getsignal$retresult" | grep -v grep |head -n 1 | awk '{print $1}')
			kill -9 $PID
			rm -f $ROOTER_LINK/getsignal$retresult
			PID=$(ps |grep "reconnect$retresult" | grep -v grep |head -n 1 | awk '{print $1}')
			kill -9 $PID
			rm -f $ROOTER_LINK/reconnect$retresult
			PID=$(ps |grep "create_proto$retresult" | grep -v grep |head -n 1 | awk '{print $1}')
			kill -9 $PID
			rm -f $ROOTER_LINK/create_proto$retresult
			PID=$(ps |grep "processsms$retresult" | grep -v grep |head -n 1 | awk '{print $1}')
			kill -9 $PID
			rm -f $ROOTER_LINK/processsms$retresult
			PID=$(ps |grep "con_monitor$retresult" | grep -v grep |head -n 1 | awk '{print $1}')
			kill -9 $PID
			rm -f $ROOTER_LINK/con_monitor$retresult
			PID=$(ps |grep "mbim_monitor$retresult" | grep -v grep |head -n 1 | awk '{print $1}')
			kill -9 $PID
			rm -f $ROOTER_LINK/mbim_monitor$retresult
			if [ -e /usr/lib/gps/gpskill.sh ]; then
				/usr/lib/gps/gpskill.sh $retresult
			fi
			PID=$(ps |grep "chkconn1.sh" | grep -v grep |head -n 1 | awk '{print $1}')
			kill -9 $PID

			$ROOTER/signal/status.sh $retresult "No Modem Present"
			$ROOTER/log/logger "Disconnect (Removed) Modem #$retresult"
			display_top; display "Remove : $DEVICENAME : Modem $retresult"; display_bottom
			check_all_empty
			rm -f /tmp/usbwait
			rm -f /tmp/mdown$retresult
			rm -f /tmp/msimdata$retresult
			rm -f /tmp/msimnum$retresult
			rm -f /tmp/modgone
			rm -f /tmp/bmask
			rm -f /tmp/simpin$retresult
			rm -f /tmp/simpinok$retresult
		fi
	else
		IDV=$(uci get mjpg-streamer.camera.idv)
		if [ ! -z $IDV ]; then
			if [ $DEVICENAME = $IDV ]; then
				uci delete mjpg-streamer.camera
				uci commit mjpg-streamer
				/etc/init.d/mjpg-streamer stop
				log "Stop MJPEG-Streamer"
			fi
		fi
		IDV=$(uci get p910nd.printer.idv)
		if [ ! -z $IDV ]; then
			if [ $DEVICENAME = $IDV ]; then
				uci delete p910nd.printer
				uci commit p910nd
				if [ ! -d /sys$DEVPATH/*/lp0 -a -f /var/run/p9100d.pid ]; then
					log "USB Printer device unplugged, stopping p910nd"
					/etc/init.d/p910nd stop
					# p910nd does not seem to remove .pid file when stopped, removing it manually
					rm /var/run/p9100d.pid
				fi
			fi
		fi
	fi
fi

if [ "$ACTION" = "motion" ]; then
	logger webcam motion event
fi
