#!/bin/sh
#
### BEGIN INIT INFO
# Provides:          softmodem sl-modem-daemon
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Required-Start:    $local_fs $remote_fs
# Required-Stop:     $local_fs $remote_fs
# Short-Description: Setup the SmartLink modem daemon
# Description:       Starts the modem daemon emulating a serial device and
#                    links the result to /dev/modem.
### END INIT INFO


PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/slmodemd
NAME=slmodemd
PIDFILE=/var/run/$NAME.pid
DESC="SmartLink modem daemon"
modprobe="$(cat /proc/sys/kernel/modprobe 2>/dev/null || echo modprobe)"

test -x $DAEMON || exit 0

# there may be old options there...
test -r /etc/default/slmodemd && . /etc/default/slmodemd

# but most likely they are here
test -r /etc/default/sl-modem-daemon && . /etc/default/sl-modem-daemon

ALSADEVPREFIX=modem
driverlist="snd-intel8x0m snd-via82xx-modem snd-atiixp-modem"

# must match the names in /proc/modules with the underscores etc., includes slamr too
unloadllist="snd_intel8x0m snd_via82xx_modem snd_atiixp_modem slamr"

alsaload() {

    unset aplay_grep_line;
    unset proc_grep;

    # first check for situation when there is modem subdevice (aplay -l output have "(M|m)odem" string, and /proc/asound/cards doesn't).
    # this one doesn't need modprobe (modem is part of sound card chip)

    if ! proc_grep=$(grep -i "\[Modem   " /proc/asound/cards) ; then
    # if there is aplay output, get card and device numbers and form SLMODEMD_DEVICE as hw:a,b
        if aplay_grep=$(LC_ALL=C aplay -l | egrep '^card [0-9].*(M|m)odem') ; then
            aplay_grep_line=$(echo "$aplay_grep" | sed -r 's/^card ([[:digit:]]+).*device ([[:digit:]]+).*$/\1 \2/')

            # Let's configure subdevice
            if [ -n "$aplay_grep_line" ] ; then
                set $aplay_grep_line
                # This one needs hw as prefix
                ALSADEVPREFIX="hw"
                SLMODEMD_DEVICE="$ALSADEVPREFIX:$1,$2"
                ALSA=yes
                return 0
            fi
       # if there is no aplay and proc output, try to modprobe and then check for modem cards again
        else
            # first check to not do unneccessary modprobe calls. Some people even put
            # it into the kernel image

            for x in $driverlist ; do $modprobe $x 2>/dev/null ; done

            for start_reps in `seq 100` ; do
                test -e /proc/asound/cards && proc_grep=$(grep -i "\[Modem   " -i /proc/asound/cards) && (LC_ALL=C aplay -l | egrep '^card [0-9]*\: Modem ' >/dev/null) && break
                sleep 0.1
            done

        fi
    fi
	
    # if we got proc_grep (already existed or from previous if), let's use it to form SLMODEMD_DEVICE as modem:a
    if [ -n "$proc_grep" ] ; then
        # ALSA driver is loaded, use it
        set $proc_grep
        SLMODEMD_DEVICE=$ALSADEVPREFIX:$1
        ALSA=yes
        return 0
    fi

    return 1
}

config() {
   if test "$DONTSTART" = 1 ; then
      test "$BEQUIET" = 1 || echo "Not starting $DESC (options not set in /etc/default/slmodemd)"
      exit 0
   fi

   if test "$SLMODEMD_COUNTRY" ; then
      OPTS="$OPTS -c $SLMODEMD_COUNTRY"
   fi

   ALSA=`echo $SLMODEMD_DEVICE | grep :`
   
   if [ "`echo $SLMODEMD_DEVICE | grep auto`" ] ; then

       # carefully look for signs of loaded drivers
       if grep -i "\[Modem   " -i /proc/asound/cards ; then
           # already loaded, just pick up the device there
           alsaload;
       else
           # ALSA not loaded yet, try the smartlink driver first, then try ALSA
           # though (forced loading)
           if grep -q 'slamr\..*o' /lib/modules/`uname -r`/modules.dep ;
           then
               if $modprobe slamr 2>&1 | grep -q not.found ; then
                   alsaload;
               else
                   SLMODEMD_DEVICE=slamr0
               fi
           else
               alsaload;
           fi
       fi
   fi

   if [ "$ALSA" ] ; then
       # either detected or choosed by user, the driver must already be loaded
       # and the device name be picked up before

       OPTS=" --alsa $OPTS $SLMODEMD_DEVICE"

   else

      if test "$SLMODEMD_DEVICE" ; then
         OPTS="$OPTS /dev/$SLMODEMD_DEVICE"
      fi
      
      if uname -a | grep -q x86_64 ; then
         echo "Only access through ALSA is available on amd64 but slamr driver was chosen!"
         echo "Make sure that an ALSA driver for your chipset is available and is loaded"
         echo "and that access to SmartLink modem components is supported by it."
         exit 1
      fi

      # installed as module so just load it or bail out
      if MODPROBE_OPTIONS="" $modprobe slamr 2>&1 | grep -q not.found ; then
          echo "SmartLink modem driver not available for this Kernel. Please read README.Debian"
          echo "or try to install the package sl-modem-source. Exiting..."
          exit 1
      fi
   fi
}

start() {

    echo -n "Starting SmartLink Modem driver for: $SLMODEMD_DEVICE"
    ulimit -Hl unlimited; ulimit -Sl unlimited
    start-stop-daemon --start --pidfile $PIDFILE --exec $DAEMON --make-pidfile --background --quiet -- $OPTS
    RETVAL=$?
    if [ "$RETVAL" = 0 ] && [ "$NOSYMLINK" != 1 ] ; then
        echo "."
        echo "Creating /dev/modem symlink, pointing to: /dev/ttySL0."
        ln -sf ttySL0 /dev/modem
    fi
}

stop() {
    echo -n "Shutting down SmartLink Modem driver normally"
    RETVAL=0
    if [ "`pidof $NAME`" ] ; then 
        if start-stop-daemon --stop --quiet --pidfile $PIDFILE --exec $DAEMON --retry 1 ; then
            echo .
        else
            echo " probably failed."
            echo "Trying it the hard way (send SIGKILL all $NAME processes): " 
            killall -KILL $NAME || RETVAL=1
        fi
    else
        echo " ... no $NAME daemon running."
    fi
    test "$RETVAL" -ne 0 || rm -f "$PIDFILE"
    echo -n "Unloading modem driver from kernel ... " 
    msg="none found."
    for x in $unloadllist ; do 
        if grep -l -q "^$x " /proc/modules ; then
            $modprobe -r $x 2>/dev/null && msg="$x." || msg="failed."
        fi
    done
    echo $msg
}

status() {
    echo -n "Status of $DESC: "
    if [ ! -r "$PIDFILE" ]; then
        echo "$NAME is not running."
        exit 3
    fi
    if read pid < "$PIDFILE" && ps -p "$pid" > /dev/null 2>&1; then
        echo "$NAME is running."
        exit 0
    else
        echo "$NAME is not running but $PIDFILE exists."
        exit 1
    fi
}

# See how we were called. Consider udev action too.
case "$1$ACTION" in
    
    start)
    config
    start
    ;;

    add)
    ALSA=""
    # slusb via udev part
    if [ "$DEVICE" ] ; then 
       SLMODEMD_DEVICE="$DEVICE"
    else
       SLMODEMD_DEVICE="$DEVNAME"
    fi

    if [ -r "$SLMODEMD_DEVICE" ]
    then
       # check if $GROUP really exists
       if getent group $GROUP > /dev/null; then
          chmod 660 "$SLMODEMD_DEVICE"
          chown root:$GROUP "$SLMODEMD_DEVICE"
       fi
    else
       exit 1
    fi
    start
    ;;

    stop|remove)
    stop
    ;;
    
    restart|reload|force-reload)
    stop
    config
    start
    ;;
    
    status)
    status
    ;;

    *)
    echo "Usage: /etc/init.d/sl-modem-daemon {start|stop|restart|status}"
    exit 1
esac

