#! /bin/bash
# 
# Laptop mode tools module, called from /usr/sbin/laptop_mode.
# Configuration in /etc/laptop-mode/conf.d/wireless-ipw-power.conf.
#
# PURPOSE: power saving for the Intel IPW3945, IPW2200 and IPW2100
#          wireless adaptors.
#
# This script relies upon the name of the driver.
#
# Original source: http://ubuntuforums.org/showthread.php?t=419772

if [ x$CONTROL_IPW_POWER == x1 ] ; then

	# Provide defaults for config file settings
	if [ x$IPW3945_AC_POWER = x ] ; then
		IPW3945_AC_POWER=6
	fi
	if [ x$IPW3945_BATT_POWER = x ] ; then
		IPW3945_BATT_POWER=7
	fi
	if [ x$IPW2100_AC_POWER = x ] ; then
		IPW3945_AC_POWER=0
	fi
	if [ x$IPW2100_BATT_POWER = x ] ; then
		IPW3945_BATT_POWER=5
	fi

	I3945_DRIVERNAME=ipw3945
	I2200_DRIVERNAME=ipw2200
	I2100_DRIVERNAME=ipw2100

	# find executables
	if [ -x /sbin/iwpriv ] ; then
		IWPRIV=/sbin/iwpriv
	elif [ -x /usr/sbin/iwpriv ] ; then
		IWPRIV=/usr/sbin/iwpriv
	else
		echo "iwpriv is not installed" >> $OUTPUT
	fi
	if [ -x /sbin/iwconfig ] ; then
		IWCONFIG=/sbin/iwconfig
	elif [ -x /usr/sbin/iwconfig ] ; then
		IWCONFIG=/usr/sbin/iwconfig
	else
		echo "iwconfig is not installed" >> $OUTPUT
	fi

	SET_I3945_AC_PARMS="set_power $IPW3945_AC_POWER"
	SET_I3945_BAT_PARMS="set_power $IPW3945_BATT_POWER"

	SET_I2200_AC_PARMS="power off"
	SET_I2200_BAT_PARMS="power on"

	SET_I2100_AC_PARMS_1="power off"
	SET_I2100_BAT_PARMS_1="power on"
	SET_I2100_AC_PARMS_2="set_power $IPW2100_AC_POWER"
	SET_I2100_BAT_PARMS_2="set_power $IPW2100_BATT_POWER"


	#
	# Find all the wireless devices using the supplied driver names.
	# Place the interface names on the list WIFI_IFNAMES.
	#
	function findWifiIfsByDriver {
	    local DEVICE;
	    local LINK_TARGET;
	    WIFI_IFNAMES=""

	    for DEVICE in /sys/class/net/*; do
		if [ -d $DEVICE/wireless ]; then
	# See if the driver for $DEVICE matches the supplied one by checking the link to
	# the driver.
		    if [ -h $DEVICE/device/driver ]; then
			LINK_TARGET=`readlink $DEVICE/device/driver | sed 's/.*\///'`

			if [ $LINK_TARGET == $1 ]; then

	# add the interface name to the list
			    WIFI_IFNAMES=$WIFI_IFNAMES" "`echo -n $DEVICE | sed 's/.*\///'`
			fi
		    fi
		fi
	    done
	}


	#
	# Set all the adaptors using the supplied driver into the supplied
	# power saving mode
	#
	# $1 - driver name
	# $2 - power command
	# $3 - power command arguments
	#
	function setWifiPwrSave {
		local DEVICE;
		findWifiIfsByDriver $1;

		for DEVICE in $WIFI_IFNAMES; do
			echo "Wireless power saving: $2 $DEVICE $3" >> $OUTPUT
			$2 $DEVICE $3
		done
	}

	function intel3945_BatPwrSave {
		setWifiPwrSave "$I3945_DRIVERNAME" "$IWPRIV" "$SET_I3945_BAT_PARMS"
	}

	function intel3945_AcPwrSave {
		setWifiPwrSave "$I3945_DRIVERNAME" "$IWPRIV" "$SET_I3945_AC_PARMS"
	}

	function intel2200_BatPwrSave {
		setWifiPwrSave "$I2200_DRIVERNAME" "$IWCONFIG" "$SET_I2200_BAT_PARMS"
	}

	function intel2200_AcPwrSave {
		setWifiPwrSave "$I2200_DRIVERNAME" "$IWCONFIG" "$SET_I2200_AC_PARMS"
	}

	function intel2100_BatPwrSave {
		setWifiPwrSave "$I2100_DRIVERNAME" "$IWCONFIG" "$SET_I2100_BAT_PARMS_1"
		setWifiPwrSave "$I2100_DRIVERNAME" "$IWPRIV" "$SET_I2100_BAT_PARMS_2"
	}

	function intel2100_AcPwrSave {
		setWifiPwrSave "$I2100_DRIVERNAME" "$IWCONFIG" "$SET_I2100_AC_PARMS_1"
		setWifiPwrSave "$I2100_DRIVERNAME" "$IWPRIV" "$SET_I2100_BAT_PARMS_2"
	}


	if [ $ON_AC -eq 1 ] ; then
		intel3945_AcPwrSave
		intel2200_AcPwrSave
		intel2100_AcPwrSave
	else
		intel3945_BatPwrSave
		intel2200_BatPwrSave
		intel2100_BatPwrSave
	fi
else
	echo "Intel IPW Wireless power setting is disabled." >> $OUTPUT
fi
