#!/bin/bash
#
#    eee-bpw /usr/sbin/bpw start connection
#    Copyright (C) 2008  James Cameron (quozl@laptop.org)
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

# default values, edit /etc/bpw.conf not this file
APN="telstra.bigpond"
USERNAME=""
PASSWORD=""
UDEV_TRIGGERS_PPPD=no
DEBUG=no
DEVICE=/dev/bpw

# accept customisation
. /etc/bpw.conf

# allow /usr/sbin/chat to see the important values
export APN
export USERNAME
export PASSWORD

# in debug mode, report activation
PPPD_DEBUG_OPTIONS=""
case "${DEBUG}" in
    1|y|yes)
        echo "bpw: all remaining output is being redirected to /tmp/bpw-debug.$$.txt"
        exec 2>&1 > /tmp/bpw-debug.$$.txt
	echo "bpw: debug pid $$"
	date
	uname -a
	env
	ls -l ${DEVICE}
	PPPD_DEBUG_OPTIONS="debug dump"
	;;
esac

# do nothing more if asked not to
if test "${ACTION}" = "add"; then
    case "${UDEV_TRIGGERS_PPPD}" in
	0|n|no)
	    echo "bpw: ignoring event, as UDEV_TRIGGERS_PPPD is set to no"
	    exit 0
	    ;;
    esac
fi

# wait for device to appear
until [ -e ${DEVICE} ]; do
    echo "bpw: waiting for ${DEVICE} to appear"
    sleep 1
done

function connect {
    echo -n ${PASSWORD} | /usr/sbin/pppd \
        call bpw ${DEVICE} \
        nodetach ${PPPD_DEBUG_OPTIONS} \
        name "${USERNAME}" \
        connect \
        "/usr/sbin/chat -E -v -e -t1 -f /etc/chatscripts/bpw" \
        plugin passwordfd.so passwordfd 0 ${*}
    # design note: use of /bin/bash at head of file is necessary to
    # ensure echo is a builtin, otherwise the password may appear on
    # the process listing.
}

# start internet connection, and retry if appropriate return is detected
while true; do
    connect ${*} && exit 0
    RC=$?
    if [ ! -e ${DEVICE} ]; then
	echo "bpw: device no longer present, return code ${RC}"
	echo "bpw: diagnosis: USB modem was removed or powered off"
	exit
    fi
    case "${RC}" in
       1)   echo "bpw: an immediately fatal error of some kind occurred, such as an essential system call failing, or running out of virtual memory."
	    echo "bpw: diagnosis: something is badly wrong, we must avoid making it worse, exit immediately"
	    exit ${RC} ;;
       2)   echo "bpw: an error was detected in processing the options given, such as two mutually exclusive options being used."
	    echo "bpw: diagnosis: configuration error here"
	    exit ${RC} ;;
       3)   echo "bpw: pppd is not setuid-root and the invoking user is not root."
	    echo "bpw: diagnosis: configuration error here"
	    exit ${RC} ;;
       4)   echo "bpw: the kernel does not support PPP, for example, the PPP kernel driver is not included or cannot be loaded."
	    echo "bpw: diagnosis: configuration error here"
	    exit ${RC} ;;
       5)   echo "bpw: pppd terminated because it was sent a SIGINT, SIGTERM or  SIGHUP signal."
	    echo "bpw: diagnosis: intentional connection shutdown by user"
	    exit ${RC} ;;
       6)   echo "bpw: the serial port could not be locked."
	    echo "bpw: diagnosis: configuration error here, e.g. /var read-only, or there is another process such as the plug-in event running"
	    exit ${RC} ;;
       7)   echo "bpw: the serial port could not be opened."
	    echo "bpw: diagnosis: something else has it open, or it is missing"
	    exit ${RC} ;;
       8)   echo "bpw: the connect script failed (returned a non-zero exit status)."
	    echo "bpw: diagnosis: modem may not be attached to network, retrying."
	    # TODO: report in GUI
	    sleep 0.3 ;;
       9)   echo "bpw: the command specified as the argument to the pty option could not be run."
	    echo "bpw: diagnosis: configuration error here, we do not use the pty option"
	    exit ${RC} ;;
       10)  echo "bpw: the PPP negotiation failed, that is, it didn't reach the point where at least one network protocol (e.g. IP) was running."
	    echo "bpw: coverage may be lost, retrying after five seconds"
	    # TODO: report in GUI
	    sleep 5 ;;
       11)  echo "bpw: the peer system failed (or refused) to authenticate itself."
	    echo "bpw: diagnosis: configuration error here, we must not ask the peer to authenticate"
	    exit ${RC} ;;
       12)  echo "bpw: the link was established successfully and terminated because it was idle."
	    echo "bpw: diagnosis: additional configuration intentional here"
	    exit ${RC} ;;
       13)  echo "bpw: the link was established successfully and terminated because the connect time limit was reached."
	    echo "bpw: diagnosis: additional configuration intentional here"
	    exit ${RC} ;;
       14)  echo "bpw: callback was negotiated and an incoming call should arrive shortly."
	    echo "bpw: diagnosis: configuration error here"
	    exit ${RC} ;;
       15)  echo "bpw: the link was terminated because the peer is not responding to echo requests."
	    echo "bpw: diagnosis: loss of coverage"
	    exit ${RC} ;;
       16)  echo "bpw: the link was terminated by the modem hanging up."
	    echo "bpw: diagnosis: no USIM present, access point name incorrect, or username or password wrong"
	    exit ${RC} ;;
       17)  echo "bpw: the PPP negotiation failed because serial loopback was detected."
	    echo "bpw: diagnosis: configuration error here"
	    exit ${RC} ;;
       18)  echo "bpw: the init script failed (returned a non-zero exit status)."
	    echo "bpw: diagnosis: configuration error here, we don't use an init script"
	    exit ${RC} ;;
       19)  echo "bpw: we failed to authenticate ourselves to the peer."
	    echo "bpw: diagnosis: the username and password in the modem set at registration does not match the username and password being used now."
	    exit ${RC} ;;
       *)   echo "bpw: pppd exit code ${RC}"
	    echo "bpw: diagnosis: unknown cause, the exit code is not documented in man pppd"
	    exit ${RC} ;;
    esac
done
