Setting tag planetlab-umts-tools-0.7-1
[planetlab-umts-tools.git] / backend / umts_functions
index c97c321..928f602 100644 (file)
@@ -1,73 +1,38 @@
 #!/bin/bash
 
-PPPD_PIDFILE=/var/run/umts_pppd.pid
-
-PPPD=pppd
 
 STROK="remote IP address"
-
-PPP_INT=ppp0
-
-GCOM=""
-
+GCOMP="comgt"
+GCOM="/usr/bin/"${GCOMP}
 LOGF="/tmp/umtslogs"
-
+PPPD_PIDFILE="/var/run/umts_pppd.pid"
 DESTS_FILE="/tmp/umts_dest_file"
-
 FILE_TEMP_NID="/tmp/umts_temp_nid"
-
 FILE_UMTS_INT="/tmp/umts_dev"
+LOCK_DIR="/tmp/umts_lock_d"
+FILE_LOCK_SLIVER="/tmp/umts_locking_sliver"
+PPP_INT="ppp0"
+PPPD="pppd"
+CHAT_SCRIPTS="/etc/chatscripts"
+UMTS_CONF="/etc/umts.conf"
 
 
-function set_umts_dev(){
-       echo $1 > $FILE_UMTS_INT
-}
 
 function get_umts_dev(){
-       cat $FILE_UMTS_INT
+       echo "/dev/umts_modem"
 }
 
-
-function start_gcom(){
-    if ! $GCOM -d `get_umts_dev`; then
-       return 1;
-    fi
-
-    return 0
-}
-
-function init(){
-       local found=1
-
-       modprobe nozomi
-       modprobe serial_cs
-
-       if [ -f /usr/bin/gcom ]; then 
-               GCOM=/usr/bin/gcom
-       elif [ -f /usr/bin/comgt ]; then
-               GCOM=/usr/bin/comgt
-       else
-               echo "I couldn't find gcom"
-               return 1;
-       fi
-
-       for i in /dev/umts_modem /dev/umts_modem1; do   
-               echo "Testing if the umts interface is present on the device $i..."
-               if $GCOM -d $i; then
-                       found=0
-                       set_umts_dev $i 
-                       break
-               fi      
-       done 
+function init_umts(){
+       #local found=1
        
-       if ! [  $found == 0 ]; then
-               echo "I couldn't find the umts device; make a symlink from it to /dev/umts_modem"
-               return 1
+       if [ -e $LOCK_DIR ]; then
+               rmdir $LOCK_DIR
        fi
 
-       if ! grep umts_table /etc/iproute2/rt_tables > /dev/null 2>&1; then
-               echo "20 umts_table" >> /etc/iproute2/rt_tables
-       fi
+       # the routing table is now managed by sliceip
+       #if ! grep "umts_table" /etc/iproute2/rt_tables > /dev/null 2>&1; then
+       #       echo "20 umts_table" >> /etc/iproute2/rt_tables
+       #fi
 
        return 0
 
@@ -82,31 +47,27 @@ function get_temp_nid(){
 #called when the connection is started
 function conn_on(){
        local sliver=$1
-       #local sliver_nid=$2
 
        #DESTS_FILE contains added destinations
        rm -f $DESTS_FILE 
-       touch $DESTS_FILE > /dev/null 2>&1
-
-       set_temp_nid $sliver_nid
-
-       set_routes $sliver
 
        cat $LOGF | grep "local"
        return 0
 
 }
 
-#called when the connection is terminated
+#called when the connection is terminated to remove the rules
+#on the destinations reachable thorugh the UMTS device
 function conn_off(){
        local sliver=$1
-       #local sliver_nid=$2
+       local ppp_addr=$2
 
-       unset_routes $sliver
+# Not needed anymore as the killing of the PPP connection
+# makes the rules pointing to it automatically disappear.
 
-       for i in `cat $DESTS_FILE`; do
-               del_destination $i $sliver > /dev/null 2>&1
-       done
+#      for i in `cat $DESTS_FILE`; do
+#              del_destination $i $sliver > /dev/null 2>&1
+#      done
 
        rm $DESTS_FILE >/dev/null 2>&1
 }
@@ -114,20 +75,36 @@ function conn_off(){
 function start_umts(){
     local sliver=$1
     local sliver_nid=`get_nid $sliver`
-   
-    
+
+    if ! lock $sliver; then
+       return 1
+    fi 
+
     if status_umts; then
         echo "Already connected"
         return 0; 
     fi
-
-    if ! [ -c `get_umts_dev` ]; then
-       echo "Umts interface not present"
+    
+    echo "Starting GCOM..."
+    if ! $GCOM -d `get_umts_dev`; then
+       unlock $sliver
        return 1
     fi
 
     rm -f $LOGF
 
+    if [ -e $UMTS_CONF ]; then
+       . $UMTS_CONF
+    fi
+    if ! [[ $APN ]]; then
+       APN="web.omnitel.it"
+    fi
+    if ! [[ $NUM ]]; then
+        NUM="*99***1#"
+    fi
+    
+
     exec /usr/sbin/pppd nodetach `get_umts_dev` 460800 \
                0.0.0.0:0.0.0.0 \
                connect "/usr/sbin/chat -v                     \
@@ -136,18 +113,18 @@ function start_umts(){
                ABORT           '\nNO ANSWER\r'                \
                ABORT           '\nRINGING\r\n\r\nRINGING\r'   \
                ''              ATZ     OK 'ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0' OK  \
-               ATD*99***1#    CONNECT ''" > $LOGF &
+               'AT+CGDCONT=1,\"IP\",\"$APN\"' OK \
+               ATD$NUM   CONNECT ''" > $LOGF &
+
 
     echo $! > $PPPD_PIDFILE
 
-       
     sleep 5s;  #waiting for the interface to establish the link
     if grep "$STROK" $LOGF >/dev/null 2>&1; then
-       
        conn_on $sliver $sliver_nid
     else
        #second try
-       sleep 4s;
+       sleep 5s;
        if grep "$STROK" $LOGF >/dev/null 2>&1; then
            conn_on $sliver $sliver_nid
        else
@@ -158,49 +135,59 @@ function start_umts(){
 }
 
 
-
-
+# stop the UMTS connection by killing the pppd daemon and
+# then by calling conn_off
 function stop_umts(){
     local sliver=$1
+    local sliver_nid=`get_nid $sliver`
+    local ppp_addr
 
     if ! [ -e $PPPD_PIDFILE ]; then 
        echo "Disconnected"
        return 0;
     fi
 
+    ppp_addr=`get_ppp_address`
+
+    if ! check_who_locked $sliver; then
+       return 1
+    fi
+
     PID=`cat $PPPD_PIDFILE`;
 
     if [ -d /proc/$PID ] &&  grep $PPPD /proc/$PID/cmdline >/dev/null 2>&1; then       
-       #del_interface $1;
-       conn_off $sliver `get_nid $sliver`
-       kill $PID;
-       sleep 5;
+       kill $PID;      
+       touch $DESTS_FILE
+       sleep 2s;
     fi
 
     if status_umts; then
        return 1;
     else
+       conn_off $sliver $ppp_addr
        cat $LOGF | grep "time"
        rm $PPPD_PIDFILE
+       unlock $sliver;
        return 0
     fi
 }
 
-
+# check the status of the umts connection by looking at then
+# state of pppd daemon
 function status_umts(){
-
+    local sliver=$1
+       
     if ! [ -e $PPPD_PIDFILE ]; then return 1; fi
-
     PID=`cat $PPPD_PIDFILE`
 
     if [ -d /proc/$PID ] &&  grep $PPPD /proc/$PID/cmdline >/dev/null 2>&1; then
-       return 0;
+        return 0;
     else 
        return 1;
     fi
 }
 
-#add the ppp interface from the slice - not used at the moment
+#add the ppp interface to the slice - not used at the moment
 function add_interface(){
     local nid=`get_nid $1`
     $NADDRESS --add --nid $nid --ip $PPP_INT >>$LOGFILE 2>&1;
@@ -217,83 +204,60 @@ function get_nid(){
     id -u ${1}
 }
 
-function set_routes(){
-       local sliver=$1
-       local sliver_nid=`get_nid $sliver`
-       local temp_nid=`get_temp_nid`
-       local ppp_addr=`get_ppp_address`
-
-       #remarking of packets to trigger rerouting and SNAT
-       iptables -t mangle -A OUTPUT -j MARK --copy-xid 0x00
-       iptables -t mangle -A OUTPUT -m mark --mark $sliver_nid -j MARK --set-mark $temp_nid
-       iptables -t nat -A POSTROUTING -o $PPP_INT -j SNAT --to-source `get_ppp_address`
-       iptables -t mangle -I POSTROUTING 1 -m mark --mark $temp_nid -j MARK --set-mark $sliver_nid
-       
-       #enable the explicit bind to the ppp interface
-       ip route flush table umts_table >/dev/null 2>&1 
-       ip rule add from $ppp_addr fwmark `get_temp_nid` table umts_table >/dev/null 2>&1
-       ip route add default dev $PPP_INT src `get_ppp_address` table umts_table >/dev/null 2>&1
-       ip route flush cache  >/dev/null 2>&1
-}
 
-function unset_routes(){
-       local sliver=$1
-       local sliver_nid=`get_nid $sliver`
-       local temp_nid=`get_temp_nid`
-       local ppp_addr=`get_ppp_address`
-
-       #remarking and SNAT removed 
-       iptables -t mangle -D OUTPUT -j MARK --copy-xid 0x00
-       iptables -t mangle -D OUTPUT -m mark --mark $sliver_nid -j MARK --set-mark $temp_nid
-       iptables -t nat -D POSTROUTING -o $PPP_INT -j SNAT --to-source `get_ppp_address`
-       iptables -t mangle -D POSTROUTING -m mark --mark $temp_nid -j MARK --set-mark $sliver_nid
+# check if sliceip is activated for the slice
+function check_sliceip(){
+  
+  if ! [ -e /vsys/sliceip ]; then
+    echo "Sliceip is not installed. Exiting."
+    return 1
+  fi
+  
+}
 
-       #disable the explicit bind to the ppp interface
-       ip rule del from $ppp_addr fwmark `get_temp_nid` table umts_table  >/dev/null 2>&1
-       ip route del default dev $PPP_INT  src `get_ppp_address` table umts_table >/dev/null 2>&1
-       ip route flush cache  >/dev/null 2>&1
+# Deliver a command to sliceip (basically to set the destinations to be
+# reached through the UMTS device)
+function sliceip_cmd(){
 
+  local command=$2
+  local sliver=$1
+  
+  echo "$command" | /vsys/sliceip $sliver
+  
 }
 
+# Add a destination to be reached through the UMTS device
 function add_destination(){
        local dest="$1"
        local sliver=$2
-       
-       local sliver_nid=`get_nid $sliver`
-
-       local temp_nid=`get_temp_nid`
 
        if [[ ! $dest ]]; then return 1; fi
 
        if ! status_umts; then
                return 1;
        fi
-       
-       if ip rule add to "$dest" fwmark $temp_nid table umts_table >/dev/null 2>&1; then
-               echo "$dest" >> $DESTS_FILE
-               return 0
-       else 
-               return 1        
+
+       if ! check_who_locked $sliver; then
+               return 1;
        fi
-       ip route flush cache  >/dev/null 2>&1
+
+       sliceip_cmd $sliver "route add $dest dev ${PPP_INT}"    
+         
 }
 
+# Delete a destination that was previously reached through the UMTS device.
 function del_destination(){
        local dest="$1"
        local sliver=$2
-
-       local sliver_nid=`get_nid $sliver`
-
-       local temp_nid=`get_temp_nid`
-
+       
        if [[ ! $dest ]]; then return 1; fi
-       #old - if ip route del to "$dest" dev $PPP_INT >/dev/null 2>&1; then
-       if ip rule del to "$dest" fwmark $temp_nid table umts_table >/dev/null 2>&1; then
-               return 0;
-       else 
+
+       if ! check_who_locked $sliver; then
                return 1;
        fi
-       ip route flush cache  >/dev/null 2>&1
+
+       sliceip_cmd $sliver "route del $dest dev ${PPP_INT}";
+
 }
 
 
@@ -301,29 +265,92 @@ function get_ppp_address(){
        ifconfig $PPP_INT | grep inet\ addr | cut -d ":" -f 2 | cut -d " " -f 1
 }
 
-function set_temp_nid(){
-       local sliver_nid=$1
-       local temp_nid=$((0x20000+$sliver_nid))
 
-       #k=0
-       #temp_nid=$sliver_nid
+function check_who_locked(){
+       local sliver=$1
+       local sliver_nid=`get_nid $sliver`
+       local ret=0
+
+       if [ -e $LOCK_DIR ]; then
+               if [[ `cat $FILE_LOCK_SLIVER` != $sliver_nid ]]; then
+                       echo "Interface in use by another slice.";
+                       ret=1
+               fi
+       else
+               ret=1
+       fi
+
+       return $ret
+
+}
+
+# kill the gcom daemon
+function kill_gcom(){
+       
+       killall $GCOMP
+       sleep 3
+       if ! ps -C $GCOMP >/dev/null 2>&1; then
+               echo "$GCOMP terminated."       
+       else 
+               echo "$GCOMP still alive. Try kill -9"
+               sleep 2
+
+               killall -9 $GCOMP
        
-       #while grep :$temp_nid: /etc/passwd; do
-       #       temp_nid=$((temp_nid+1))
-       #       k=$((k+1))
-       #       if [[ $k == 1000 ]]; then
-       #               logger "Fatal error: I couldn't find a temp_nid"
-       #               stop_umts
-       #               exit 1
-       #       fi
-       #done
+               if ! ps -C $GCOMP >/dev/null 2>&1; then
+                       echo "$GCOMP terminated."
+               else            
+                       echo "Couldn't stop $GCOMP. Please contact administrators for assistance."      
+               fi
+       fi
+}
+
+# lock the umts connection to a specific sliver.
+# only one sliver at a given time can use the UMTS device
+function lock(){
+       local sliver=$1
+#      local sliver_nid=`get_nid $sliver`
+       local ret=0
 
-       echo $temp_nid > $FILE_TEMP_NID
+       if [ -e $LOCK_DIR ]; then
+               if ! check_who_locked $sliver; then
+                       ret=1
+               fi
+       else 
+               if mkdir $LOCK_DIR >/dev/null 2>&1; then
+                       echo "$sliver_nid" > $FILE_LOCK_SLIVER
+               else
+                       ret=1
+               fi
+       fi
+
+       return $ret
+}
+
+function unlock(){
+       local sliver=$1
+       local sliver_nid=`get_nid $sliver`
+       local ret=0
 
+       if ! [ -e $LOCK_DIR ]; then
+               ret=1
+       else 
+               if ! check_who_locked $sliver; then
+                       ret=1
+               else
+                       if ! rmdir $LOCK_DIR; then
+                               ret=1
+                       fi
+               fi      
+       fi
 
+       return $ret
 }
 
 
+
+
+# checks an ip addresse for validity
 function valid_dotted_quad(){
     oldIFS=$IFS
     IFS=.