set_3g_led() {
	grep WRT54G3G /proc/diag/model >/dev/null || return 0
	echo "$1" > /proc/diag/led/3g_green
	echo "$2" > /proc/diag/led/3g_blue
	echo "$3" > /proc/diag/led/3g_blink
}

scan_3g() {
	local device

	scan_ppp "$@"
	config_get device "$1" device

	# try to figure out the device if it's invalid
	[ -n "$device" -a -e "$device" ] || {
		for device in /dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2 /dev/ttyHS0 /dev/tts/2 /dev/usb/tts/0 /dev/noz0; do
			[ -e "$device" ] && {
				config_set "$1" device "$device"
				break
			}
		done
	}

	# enable 3G with the 3G button by default
	config_get button "$1" button
	[ -z "$button" ] && {
		config_set "$1" button 1
	}
}

stop_interface_3g() {
	#set_3g_led 0 0 0
	killall gcom >/dev/null 2>/dev/null
}

setup_interface_3g() {
	local iface="$1"
	local config="$2"
	local chat="/etc/chatscripts/3g.chat"
	
	config_get device "$config" device
	config_get maxwait "$config" maxwait
	maxwait=${maxwait:-20}
	while [ ! -e "$device" -a $maxwait -gt 0 ];do # wait for driver loading to catch up
		maxwait=$(($maxwait - 1))
		sleep 1
	done

	for module in slhc ppp_generic ppp_async; do
		/sbin/insmod $module 2>&- >&-
	done

	config_get apn "$config" apn
	config_get service "$config" service
	config_get pincode "$config" pincode
	config_get mtu "$config" mtu

	config_get init_string1 "$config" init_string1
	config_get init_string2 "$config" init_string2
	config_get dial_string "$config" dial_string
	export -n -- "HSDPA_INIT_STRING1=${init_string1:-"AT&F"}"
	export -n -- "HSDPA_INIT_STRING2=${init_string2:-"ATE0V1X1&D2&C1S0=0"}"
	export -n -- "HSDPA_DIAL_STRING=${dial_string:-"ATD*99***1#"}"
	#logger "====> apn=$apn, pincode=$pincode, init_string1=$init_string1"
	
	#set_3g_led 1 0 1
	
	# figure out hardware specific commands for the card
	case "$service" in
		cdma|evdo) chat="/etc/chatscripts/evdo.chat";;
	*)
		cardinfo=$(gcom -d "$device" -s /etc/gcom/getcardinfo.gcom)
		if echo "$cardinfo" | grep Novatel; then
			case "$service" in
				umts_only) CODE=2;;
				gprs_only) CODE=1;;
				*) CODE=0;;
			esac
			mode="AT\$NWRAT=${CODE},2"
		elif echo "$cardinfo" | grep Option; then
			case "$service" in
				umts_only) CODE=1;;
				gprs_only) CODE=0;;
				*) CODE=3;;
			esac
			if [ "$device" != "/dev/ttyHS0" ]; then	# for hso driver, do not do this, nancy
				mode="AT_OPSYS=${CODE}"
			fi
		fi
		# Don't assume Option to be default as it breaks with Huawei Cards/Sticks
		
		if [ "$pincode" == "" ]; then
			ERR=0
		else
			PINCODE="$pincode" gcom -d "$device" -s /etc/gcom/setpin.gcom || {
				ERR=$?
				#echo "$config(3g): Please check your SIM card and PIN code setting."
				#set_3g_led 0 0 0
				#return 1
				#ERR=1
			}
		fi
		
		test -z "$mode" || {
			logger "mode = $mode......................"
			MODE="$mode" gcom -d "$device" -s /etc/gcom/setmode.gcom
		}

		INUSE=$(uci -q -P /var/state get network.3gdev)

		logger "3G INUSE = $INUSE....."
		
		# fanny : for web display information
		SIG=$(gcom -d $device sig | grep Signal)
		logger "SIG=$SIG"	
		rm -f /var/state/3g>/dev/null
		echo "==3G Card Info== :">/var/state/3g
		echo "$cardinfo">>/var/state/3g
		echo "==3G Signal Strength== :">>/var/state/3g
		echo "$SIG">>/var/state/3g
		if [ "$ERR" == "1" ]; then
			echo "==3G Error== :">>/var/state/3g
			echo "Please check your SIM card and PIN code setting.">>/var/state/3g
			# Not 56K and 3G error so return directly.
			if [ "$INUSE" != "0572/1329/0" -a "$INUSE" != "0403/6001/0" ]; then
				logger "3G error. Check SIM card and PIN code setting."
				return 1
			fi
		elif [ "$ERR" == "2" ]; then
			logger "Set PIN timeout but can go on!"
		fi
		
		#step2: check if 3G device existed
		if [ "$device" != "" ]; then
			if [ "$SIG" != "" ]; then
				# If signal strength string exist already, grep directly. Reduce 2 seconds or so.
				TEST_DEV=$(echo "$SIG" | grep "Can't open device")
			else
				TEST_DEV=$(gcom -d $device sig | grep "Can't open device")
			fi
		else
			TEST_DEV=$(gcom | grep "Unable to locate default")
		fi

		if [ "$TEST_DEV" != "" ]; then
			echo "3G device not exist........."
			exit 1
		fi

		# fanny : If you are here, there must be 3G device exist.
		#INUSE=$(uci -q -P /var/state get network.3gdev)
		if [ "$INUSE" == "" ]; then
			uci -q -P /var/state set network.3gdev=xxxx/xxxx/x
		fi
		#if user do not set APN name. ex:56K modem
		if [ "$apn" == "" ]; then
			logger "Chat without APN name."
			chat="/etc/chatscripts/56k.chat"
		fi
	esac
	#set_3g_led 1 0 0

	# hso driver
	if [ "$device" = "/dev/ttyHS0" ]; then
		lock "/var/lock/3g-hso"
		hso_output="/var/hso_connect_output_temp"
		hso_init_script="/etc/chatscripts/3g_hso_init.chat"
		hso_dial_script="/etc/chatscripts/3g_hso_dial.chat"

		BACKUP3G=$(uci -q get network.3gwan.backup)

		if [ "$BACKUP3G" = "1" ]; then
			ifnum="1"
		else
			ifnum="0"
		fi
		
		hso_if="ppp"$ifnum

		logger "Hso : Start connecting"
		if [ "$apn" != "" ]; then
			( USE_APN=$apn /usr/sbin/chat -E -s -V -f $hso_init_script <$device >$device ) 2> $hso_output
			temp1=`grep "ERROR" $hso_output`
			temp2=`grep "CME" $hso_output`
			if [ -n "$temp1" -o -n "$temp2" ]; then
				logger "Hso : Failed to initialize connection but still go on..."
				cat $hso_output
				rm -f $hso_output
				#lock -u "/var/lock/3g-hso"
				#exit 0
			fi
			sleep 2
		fi
		
		hso_pip=""
		hso_counter=""
		while [ -z "$hso_pip" -a "$hso_counter" != "-----" ]
		do
			rm -f $hso_output
			hso_counter2=""
			logger "Hso : Start init modem"
			( /usr/sbin/chat -E -s -V -f $hso_dial_script <$device > $device ) 2> $hso_output
			sleep 2
			
			while [ -z "$hso_pip" -a "$hso_counter2" != "---" ]
			do
				logger "Hso : Get ip, device=$device"

				gcom -d "$device" -s /etc/gcom/hso_getip.gcom > $hso_output 2>&1
				temp1=`grep "ERROR" "$hso_output"`
				if [ -z "$temp1" ]; then
					cat $hso_output
					hso_pip=`grep "^_OWANDATA" $hso_output | cut -d, -f2`
					hso_ns1=`grep "^_OWANDATA" $hso_output | cut -d, -f4`
					hso_ns2=`grep "^_OWANDATA" $hso_output | cut -d, -f5`
				fi
				
				if [ -z "$hso_pip" ]; then
					sleep 2
				fi
				hso_counter2="${hso_counter2}-"
			done
			hso_counter="${hso_counter}-"
		done

		if [ -z "$hso_pip" ]; then
			logger "Hso : Failed to get ip"
			cat $hso_output
			rm -f $hso_output
			lock -u "/var/lock/3g-hso"
			exit 0
		fi

		logger "Hso : Setting IP address to $hso_pip"
		if [ -n "$mtu" ]; then
			ifconfig $hso_if mtu $mtu
		fi
		ifconfig $hso_if $hso_pip netmask 255.255.255.255 up
		route del default
		route add default dev $hso_if
		mv -f /etc/resolv.conf /tmp/resolv.conf.hso
		echo "nameserver	$hso_ns1" > $hso_output
		echo "nameserver	$hso_ns2" >> $hso_output
		mv $hso_output /etc/resolv.conf
		# web online status would reference this file
		cp /etc/resolv.conf /tmp/resolv.conf.auto

		set_interface_ifname "$config" "$hso_if"

		# The next line would make firewall work.
		env -i ACTION="ifup" INTERFACE="$config" DEVICE="$iface" PROTO=3g /sbin/hotplug-call "iface" &
		logger "3g.sh hso : Done"
		lock -u "/var/lock/3g-hso"
		exit 0
	fi

	#fanny test
        scan_ppp "$config"
        config_get ifname "$config" ifname
        #echo "config=$config"
        set_interface_ifname "$config" "$ifname"
	#################################################

	config_set "$config" "connect" "${apn:+USE_APN=$apn }/usr/sbin/chat -t5 -v -E -f $chat"
	start_pppd "$config" \
		noaccomp \
		nopcomp \
		novj \
		debug \
		ipcp-max-configure 20 \
		ipcp-max-failure 20 \
		nobsdcomp \
		noauth \
		lock \
		crtscts \
		${mtu:+mtu $mtu mru $mtu} \
		115200 "$device"
}
