#!/bin/sh

#*******************************************************************************
# Copyright (c) 2012 Sierra Wireless and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
#     Sierra Wireless - initial API and implementation
#*******************************************************************************

#GPRS over PPP script for ubuntu
#this script really mount ppp and alter network config

#DEPENDENCIES LIST:
#sh, pppd, chat, grep, sed, cat, route, ifconfig, ping

PPPD=pppd
CHAT=chat
modemport=/dev/ttyS0
PPPDDEVICE=ppp0
PPPDRESOLV=/etc/ppp/resolv.conf

#Files used to retrieve real ppp interface name
LINKNAME=pppRA
LINKNAMEFILE=/var/run/ppp-${LINKNAME}.pid

apn=""

CHATSTART=/tmp/chatstart
CHATSTOP=/tmp/chatstop

PINGTIMEOUT=10

#DEBUG file with some log
#As commands outputs/results are done using stdout, debugging has to be done using a file...
LOGFILE=/tmp/GRPS.sh.log
CONFPPP="true"

buildChatScript()
{
    #build chat script for starting ppp connexion
    echo "'' 'AT'" >${CHATSTART}
    echo "'OK' '\dAT+CGDCONT=1,\"IP\",\"${apn}\"'" >>${CHATSTART}
    echo "'OK' 'ATE0V1'" >>${CHATSTART}
    echo "'OK' 'ATDT*99***1#'" >>${CHATSTART}
    echo "'CONNECT'" >>${CHATSTART}
    echo >>${CHATSTART}

    #build chat script for stopping ppp connexion
    echo "'' '+++ATH'" >${CHATSTOP}
    echo "'NO CARRIER' ''" >>${CHATSTOP}
    echo "'' 'AT'" >>${CHATSTOP}
    echo >>${CHATSTOP}
}



runPPPD()
{
    #kill any running pppd deamon
    killall -q ${PPPD}
    RETRIES=8
    while [ "$?" -eq "0" -a "${RETRIES}" -ne "0" ]
    do
        echo "retry killall $RETRIES" >> $LOGFILE
        RETRIES=$(($RETRIES - 1))
        sleep 1
        killall -q ${PPPD}
    done

    #run pppd
    ${PPPD} ${modemport} 115200 modem debug novj usepeerdns lock refuse-chap linkname ${LINKNAME} demand connect ${CHAT}' -t 15 -v -f '$CHATSTART disconnect ${CHAT}' -t 15 -v -f '$CHATSTOP 1>/dev/null 2>/dev/null
    PPPSTATUS=$?

    #get real ppp interface name
    if [ -f ${LINKNAMEFILE} -a "`cat ${LINKNAMEFILE} 2>/dev/null | wc -l`" -eq "2" ]
    then
        PPPDDEVICE=`cat  ${LINKNAMEFILE} | sed -n '$p'`
        echo "Real ppp interface name found: $PPPDDEVICE"  >> $LOGFILE
    else
        echo "can not get real ppp interface name " >> $LOGFILE
    fi

    #verifying if interface is mounted or not
    IFUP=`route -n | grep ${PPPDDEVICE} 2>/dev/null`

    if [ "$PPPSTATUS" -eq "0" ] && [ -n "${IFUP}" ] && [ -f /etc/ppp/resolv.conf ]; then #interface mount, return
        echo "all status ok"  >> $LOGFILE
        return
    else
        echo "error mounting the device: PPPSTATUS=$PPPSTATUS IFUP=${IFUP} " >> $LOGFILE
        exit 1
    fi
}

startPPP()
{
    echo "starting..."  >> $LOGFILE
    PTP=`ifconfig ${PPPDDEVICE} | sed -n 's/.*P-t-P:\(.*\) .*/\1/p'`
    if [ $PTP ]
    then
        echo "starting...PTP ok: $PTP"  >> $LOGFILE
        ping -c 10 -w $PINGTIMEOUT $PTP >/dev/null 2>/dev/null
        echo "starting...PTP ok, ping done"  >> $LOGFILE
    else
        echo "starting...PTP ko"  >> $LOGFILE
        exit 1
    fi
    #TODO
    #need improvement to return only when real ip address is set and when ppp interface is real up
    #need to be able to make diff between first start and other one?
}


getInfos()
{
    echo "getInfos..."  >> $LOGFILE
    IFCONFIG=`ifconfig  ${PPPDDEVICE} 2>/dev/null`
    IPADDR=`echo $IFCONFIG | sed -n 's_.*inet addr:\([0-9\.]\+\) .*_\1_p'`
    HWADDR=`echo $IFCONFIG | sed -n 's_.*HWaddr \([0-9:a-f]\+\).*_\1_p'`
    NETMASK=`echo $IFCONFIG | sed -n 's_.*Mask:\([0-9\.]\+\) .*_\1_p'`
    echo "getInfos..."  >> $LOGFILE

    #get the default gateway for current device, only get the first one.
    GW=`route -n | grep UG | grep ${PPPDDEVICE} | sed -n -e 's/^\([0-9\.]*\)\s*\([0-9\.]*\).*/\2/p' -e 'q'`

    echo "getInfos..."  >> $LOGFILE

    DNS=`cat $PPPDRESOLV | sed -n 's_^nameserver \([0-9\.]\+\)_\1_p'`
    echo "getInfos..."  >> $LOGFILE

    #default value "NULL" if values are undef/null
    RES="${IPADDR:-NULL} ${HWADDR:-NULL} ${NETMASK:-NULL} ${GW:-NULL} ${DNS:-NULL}"
    echo $RES
    echo "getInfos...${RES}"  >> $LOGFILE
}

echo "->command $1 on `date`"  >> $LOGFILE
for arg in $@; do
    echo param: $arg >>  $LOGFILE
done

case "$1" in

    #init command
    init)

    if [ $CONFPPP ]
    then
        if [ -f /tmp/conf.ppp ]; then
            rm /tmp/conf.ppp 1>/dev/null 2>&1
        fi

        for arg in $@; do
            if [ "$arg" != "$1" ]; then
                eval $arg;
                echo $arg >> /tmp/conf.ppp;
            fi
        done

    fi

    buildChatScript
    runPPPD
    echo $PPPDDEVICE
    exit 0
    ;;

    #start command
    start)

    if [ -z "$2" ]; then
        exit 1
    fi

    if [ $CONFPPP ]
    then
        if [ -f /tmp/conf.ppp ]; then
            . /tmp/conf.ppp
        fi
    fi


    PPPDDEVICE=$2
    startPPP
    getInfos
    exit 0
    ;;

    #stats command
    stats)
    if [ -z "$2" ]; then
        exit 1
    fi
    PPPDDEVICE=$2
    IFCONFIG=`ifconfig $PPPDDEVICE 2>/dev/null`
    RX=`echo $IFCONFIG | sed -n 's_.*RX bytes:\([0-9]\+\) .*_\1_p'`
    TX=`echo $IFCONFIG | sed -n 's_.*TX bytes:\([0-9]\+\) .*_\1_p'`

    echo $RX $TX
    exit 0
    ;;

    #default command
    default)

    if [ -z "$2" ] || [ -z "$3" ] || [ -z "$4"]; then
        exit 1
    fi

    #route
    #TODO: what if more than one default route
    route del default 1>/dev/null 2>/dev/null
    route add default gw $3 dev $2  1>/dev/null 2>/dev/null

    #DNS
    #TODO: save old /etc/resolv.conf
    mv /etc/resolv.conf /tmp/resolv.conf.save.RAnetman
    echo "#edited by ReadyAgent GPRS script" >> /etc/resolv.conf
    echo nameserver $4 >>/etc/resolv.conf
    if [ -z "$5" ]; then
        echo nameserver $5 >>/etc/resolv.conf
    fi

    exit 0
    ;;

    #stop command
    stop)
    if [ -z "$2" ]; then
        exit 1
    fi
    #   killall `basename ${PPPD}`
    #    sleep 5
    exit 0
    ;;

    *)
    exit 1
    ;;
esac
