Advanced Wifi/wrapper

From WebOS Internals
Revision as of 19:04, 1 November 2012 by Zigi004 (talk | contribs) (some typos corrections)
Jump to navigation Jump to search

This shell wrapper around wpa_supplicant inject custom wifi settings into running wpa_supplicant. More informations about topic can be found at Advanced_Wifi page.


#!/bin/sh

## This is wrapper around wpa_supplicant binary.
##
## version 0.0.1 proof of concept
## no responsibility, no warranty, works for me (Veer 8G, WebOS 2.1.2), YMMV
##
## author: Matej Zagiba
## license: any version of GPL
##
## Installation and usage:
## 1. turn off wifi
## 2. connect to Your WebOS device and copy original binary file:
##    # cp /usr/sbin/wpa_supplicant /usr/sbin/wpa_supplicant.real
## 3. put this file on wpa_supplicant's place and rename it:
##    # cp /media/internal/wpa_supplicant.wrapper /usr/sbin/wpa_supplicant
## 4. put customized config in /media/internal/.wpa_supplicant.conf
##    or any other convenient place. Remember - passwords are stored
##    in that file. Update configuration file location in WPA_CONFIG variable
## 5. from http://packages.debian.org/wheezy/wpasupplicant download package
##    with correct architecture (HP veer uses armel) extract wpa_cli binary
##    and copy it in place e.g.:
##    # cp /media/internal/wpa_cli /usr/sbin
## 6. correct permisions:
##    # chmod 755 /usr/sbin/wpa_supplicant /usr/sbin/wpa_cli
##
## Installation is now completed
##
## All networks defined in original wifi application will continue working
## and can be managed through original interface. Network settings in custom
## config file will overwrite definitions in built-in application.
## So for any configuration change in custom networks edit configuration
## file by Your favorite editor
##
## To use it:
## - first define new network in the configuration file,
##   use any option You wish, use wpa_supplicant config file format:
##     every option on single line
##     "network={" and "}" and comment also on single line,
##   best way for now is to export settings from another system
## - then turn on wifi
## - from WiFi Preferences applet select "Join network" and enter name of the network
##   You just configured, select security type - Open
## - Enjoy new wifi connection


WPA_CONFIG="/media/internal/.wpa_supplicant.conf"
WPA_CLI="/usr/sbin/wpa_cli"

## no user editable settings belove here
OIFS="$IFS"

## define functions

merge_wifi_settings ()
{
  IFS="
"
  READING_NETWORK=0
  UNKNOWN_NET=0

  # read and apply user configuration
  #
  for LINE_IN in `cat "$WPA_CONFIG"`; do
    IFS="$OIFS"

    # get rid of leading and trailing blanks and remove comments
    LINE_IN=`sed -e "s/^space:*//" -e "s/space:*$//" -e "s/^#.*$//" <<EOF
$LINE_IN`

    # skip empty lines
    [ "o$LINE_IN" = "o" ] && continue

    OPTION="${LINE_IN%%=*}"
    VALUE="${LINE_IN#*=}"

    case "$LINE_IN" in
        # start of network block
	"network={"*)
		READING_NETWORK=1
		;;
        # SSID of the network, fun starts here
        # we expect to ssid be first thing set in network block
	"ssid="*)
		NET_SSID="${VALUE#\"}"
		NET_SSID="${NET_SSID%\"}"
                # is such a network allready know by wpa_supplicant?
		NET_ENTRY=`$WPA_CLI list_networks | grep "$NET_SSID"`
		if [ "o$NET_ENTRY" = "o" ]; then
		  UNKNOWN_NET=1
		  NET_ID=`"$WPA_CLI" ADD_NETWORK | tail -n1`
		  "$WPA_CLI" SET_NETWORK "$NET_ID" "$OPTION" "$VALUE" >/dev/null
		else
		  NET_ID="${NET_ENTRY%%	*}"
		  NET_STATUS="${NET_ENTRY##*	}"
                  # are we connected to this network?
                  if [ "o$NET_STATUS" = 'o[CURRENT]' ]; then
                    # yes, so no need to reconfigure wpa_supplicant
                    READING_NETWORK=0
                  else
                    # no, so we disable network to to be able modify setting
		    "$WPA_CLI" "DISABLE_NETWORK" "$NET_ID" >/dev/null
		  fi
		fi
		;;
        # end of network block - enable network, if needed and reset variables
	"}")
                if [ "o$READING_NETWORK" = "o1" ]; then
		  "$WPA_CLI" "ENABLE_NETWORK" "$NET_ID" >/dev/null
		fi
		READING_NETWORK=0
		UNKNOWN_NET=0
		unset NET_ENTRY NET_ID NET_STATUS OPTION VALUE
		;;
        # update current option if reading network definition
	*)
		if [ "o$READING_NETWORK" = "o1" ]; then
		  "$WPA_CLI" SET_NETWORK "$NET_ID" "$OPTION" "$VALUE" >/dev/null
		fi
		;;
    esac
  done
}


## PmWiFiService will send SIGKILL to wpa_supplicant process, which could
## leave wpa_supplicant.real running and cause problems later.
## so we do some magic with processes...

if [ "o$1" = "o--SETUP-WAIT-AND-CLEANUP" ]; then
  shift
  /usr/sbin/wpa_supplicant --SLEEP-AND-UPDATE &

  ##just to be sure
  if [ -x "$WPA_CLI" ]; then
    "$WPA_CLI" terminate >/dev/null
  else
    pkill wpa_supplicant
  fi

  # SET UP THINGS
  if [ -f "$WPA_CONFIG" ]; then
    echo "" >>/tmp/.wpa_supplicant.conf
    echo "update_config=1" >>/tmp/.wpa_supplicant.conf
    /usr/sbin/wpa_supplicant.real "$@" -B
    merge_wifi_settings
  else
    /usr/sbin/wpa_supplicant.real "$@" -B
  fi

  # WAIT
  wait
  # and CLEAN UP
  if [ -x "$WPA_CLI" ]; then
    "$WPA_CLI" terminate >/dev/null
  else
    pkill wpa_supplicant
  fi
    rm -rf /tmp/.wpa_supplicant.tmp

elif [ "o$1" = "o--SLEEP-AND-UPDATE" ]; then
  # check some basic stuff - is there executable wpa_cli?
  # and does user configuration exists?
  if [ -x "$WPA_CLI" -a -f "WPA_CONFIG" ]; then
    ## - can we reach wpa_supplicant?
    "$WPA_CLI" status >/dev/null || exit $?

    while true; do
      sleep 5
      merge_wifi_settings || exit
    done
  else
    # we still want to be here and do nothing
    # just waiting to be killed by PmWiFiService ...
    while true; do
      sleep 30
    done
  fi
else
  rm -rf /tmp/.wpa_supplicant.tmp
  ln -s /usr/sbin/wpa_supplicant /tmp/.wpa_supplicant.tmp
  exec /tmp/.wpa_supplicant.tmp --SETUP-WAIT-AND-CLEANUP "$@"
fi


--Zigi004 11:04, 1 November 2012 (PDT)