#!/bin/sh

#SIM-Switcher, automated switching with a double (dual) SIM adapter.
#by peterleinchen
#http://talk.maemo.org/showthread.php?t=85722

confpath=/home/user/.config/sim-switcher
home_restored=""

read_config()
{
#$1, config file (without path)
conffile=$confpath/$1
local ret_val

if [ ! -f $conffile ]
then
  if [ -n "$verbose" ]; then
    /usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog string:"Please give a valid config file 
($conffile) ! " uint32:0 string:"OK"
  fi
  ret_txt="no conf file"
  ret_val=11
else
  source $conffile
  if [ Z"$sim" == Z"" ]
  then
    if [ -n "$verbose" ]; then
      /usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog string:"Please give at least the switching code! 
Use vi, nano, txpad, leafpad, ... to edit the config file 
($conffile) ! " uint32:0 string:"OK"
    fi
    if [ -e /usr/bin/leafpad ]
    then
      exec leafpad $conffile
      ret_text="no sim switching code, editor leafpad"
      ret_val=12
    elif [ -e /usr/bin/txpad ]
    then
      exec txpad $conffile
      ret_text="no sim switching code, editor txpad"
      ret_val=13
    elif [ -e /usr/bin/nano ]
    then
      exec nano $conffile
      ret_text="no sim switching code, editor nano"
      ret_val=14
    elif [ -e /usr/bin/vim ]
    then
      exec vim $conffile
      ret_text="no sim switching code, editor vim"
      ret_val=15
    elif [ -e /usr/bin/vi ]
    then
      exec vi $conffile
      ret_text="no sim switching code, editor vi"
      ret_val=16
    else
      ret_text="no sim switching code, no editor at all"
      ret_val=17
    fi
  else
    ret_text=""
    ret_val=0
  fi
fi

echo $ret_txt
return $ret_val
}

restore_home()
{
#kill hildon-home (if requested) for updating the operator name in status area
#if [ Z"$2" == Z"home" ]; then 
if [ Z"$1" == Z"home" ]; then 
  sleep 1
  #source /home/user/home
  cp /home/user/.config/hildon-desktop/home.plugins     /home/user/.config/sim-switcher/.tmp/home.plugins
  killall hildon-home
  sleep 7
  cp /home/user/.config/sim-switcher/.tmp/home.plugins /home/user/.config/hildon-desktop/home.plugins
  home_restored="true"
else
  home_restored="false"
fi
}

set_operator_name()
{
if [ -n "$2" ]
then
  desktopFile=/usr/share/applications/hildon/$1.desktop
  if [ -f $desktopFile ]
  then
    chkName=$(awk '{if ( $1" "$2 == "Name=""'"$1"'"" (""'"$2"'"")") print $1" "$2}' $desktopFile) 
    if [ -z "$chkName" ]
    then
      #echo "echo 'Name=$1 ($2)' >> $desktopFile" | sudo su
      sudo /opt/sim-switcher/operator-helper "Name=$1 ($2)" $desktopFile
      ret_text="operator name set to ($2) for $1.desktop"
      return 0
    fi
  else
    if [ -n "$verbose" ]; then
      /usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog string:"$ret_txt"
    fi
    ret_text="Holy sh.., no $1.desktop file. Fully messed up!"
    return 31
  fi
else
  ret_txt="no operator name given"
  return 32
fi 
}

get_SIM_details()
{
MNCMCC=$(dbus-send --system --print-reply=literal --dest=com.nokia.phone.net /com/nokia/phone/net Phone.Net.get_registration_status | tr '\n' ' ' | awk '{print $8,$10}')
MNC=$(echo $MNCMCC | cut -f1 -d' ')
MCC=$(echo $MNCMCC | cut -f2 -d' ')
OP=$(dbus-send --system --print-reply --dest=com.nokia.phone.net /com/nokia/phone/net Phone.Net.get_operator_name byte:0 uint32:$MNC uint32:$MCC | grep string | awk '{print $2 " " $3 " " $4}' | tr -d \")
echo $OP, MNC: $MNC, MCC: $MCC
}


do_switch()
{
#$1,sim        SIM switching code, as given by your adapter
#              (11*, **1, #1, ...) or likely
#$2,refhome    kill hildon home to safely refresh provider name
#              (home)
#$3,cellmode   GSM/UMTS/Dual cell modem/radio mode
#              (1,  2,   0)
#$4,connpol    connectivity policy, autoconnect to type of network
#              ([], *, WLAN_INFRA, GPRS) meaning (always ask, any, only WLAN, default GPRS conn (of switched-to SIM))
#$5,iap        autoconnect to specific IC, created via fAPN, needs to be read out via 'gconftool -R /system/osso/connectivity/IAP'
#              (name of IC_IAP)
#$6,forw_bef   set call forwarding BEFORE change, negative value means cancel
#              (1 unconditional, 2 busy, 3 no answer, 4 out of reach, 5 not available (inc:2,3,4))
#$7,forw_n_bef number to forward calls to before switching, intl. format
#              (+49...)
#$8,forw_aft   set call forwarding AFTER change, negative value means cancel
#              (1 unconditional, 2 busy, 3 no answer, 4 out of reach, 5 not available (inc:2,3,4))
#$9,forw_n_aft number to forward calls to after switching, intl. format
#              (+49...)
#$10,oper      operator name to be displayed on desktop item
#              (VF_de) please do not use more than 9 chars and NO blanks


#check for empty SIM request
if [ Z"$1" == Z"" ]; then
  if [ -n "$verbose" ]; then
    /usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog string:"Please do NOT call me without a SIM number !
(e.g. 11* or **1 or #11 or ...)" uint32:0 string:"OK"
  fi
  ret_txt="no switching code"
  return 21
fi

#check if requested SIM already active
#tmpSIM=`cat /tmp/changeSIM.tmp`
#tmpSIM=`cat /opt/sim-switcher/switchSIM.tmp`
tmpSIM=`cat /home/user/.config/sim-switcher/.tmp/currentSIM`
if [ Z"$1" == Z"$tmpSIM" ]; then
  if [ -n "$verbose" ]; then
    /usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog string:"Please do NOT call me on already selected SIM ($1) !" uint32:0 string:"OK"
  fi
  ret_txt="already active"
  return 22
fi

# check for online status before starting the switching acticity, 
# cancel only if requested via 'sim-switcher break' or 'sim-switcher cancel'
if [ -f $confpath/.onlinecheck ]
then
  if [ -f $confpath/.tmp/.break ]; then rm $confpath/.tmp/.break; fi
  scount=0
  while [ "`cat /var/run/ssc`" != "online" -a ! -f $confpath/.tmp/.break ] 
  do
    if [ -n "$verbose" ]; then
      /usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteInfoprint string:"... we need the cell modem to be online for SIM switching ..."
    fi
    if [ $scount -lt 30 ]; then
      sleep 5
      let scount+=5
    elif [ $scount -lt 60 ]; then
      sleep 10
      let scount+=10
    elif [ $scount -lt 120 ]; then
      sleep 30
      let scount+=30
    else  
      sleep 60
      let scount+=60
    fi
  done
  if [ -f $confpath/.tmp/.break ]
  then 
    if [ -n "$verbose" ]; then
      /usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog string:"Current SIM switching activity was cancelled!" uint32: string: 
    fi
    rm $confpath/.tmp/.break
    ret_txt="cancelled"
    return 23
  fi
fi

#check there is no call in progress
oncall=`dbus-send --system --type=method_call --print-reply=literal --dest=com.nokia.csd.Call /com/nokia/csd/call/1 com.nokia.csd.Call.Instance.GetStatus`
if [ Z"$oncall" != Z"   uint32 0" ]; then
  if [ -n "$verbose" ]; then
    dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog string:"SIM switching not possible while a call is ongoing!" uint32: string:
  fi
  ret_txt="on call"
  return 24
fi

#get and print SIM1 details
get_SIM_details
MNC1=$MNC
MCC1=$MCC
OP1=$OP
#echo $OP, MNC: $MNC, MCC: $MCC


# setting call forwarding for old SIM (before change)
if [ Z"$6" != Z"" ]; then
  if [ $6 -lt 0 ]; then
    let div=$6
    let div*=-1
    /usr/bin/dbus-send --system --print-reply --type=method_call --dest=com.nokia.csd.SS /com/nokia/csd/ss com.nokia.csd.SS.DivertCancel uint32:$div string: uint32:
  else 
    /usr/bin/dbus-send --system --print-reply --type=method_call --dest=com.nokia.csd.SS /com/nokia/csd/ss com.nokia.csd.SS.DivertActivate uint32:$6 string:"$7" uint32:
  fi
  sleep 5
fi

#disconnect GPRS internet
dbus-send --system --dest=com.nokia.icd /com/nokia/icd_ui com.nokia.icd_ui.disconnect boolean:true
sleep 1

#set and save new SIM
/usr/bin/dbus-send --system --print-reply --type=method_call --dest=com.nokia.csd.Call /com/nokia/csd/call com.nokia.csd.Call.CreateWith string:"$1" uint32:0
sleep 1
dbus-send --system --print-reply --dest=com.nokia.csd.Call /com/nokia/csd/call com.nokia.csd.Call.Release
#
#echo 'echo '$1' > /tmp/changeSIM.tmp' |root
#echo 'echo '$1' > /opt/sim-switcher/switchSIM.tmp' |root
echo $1 > /home/user/.config/sim-switcher/.tmp/currentSIM

#dis-/enable phonet
#sudo /sbin/ifconfig phonet0 down
sudo /opt/sim-switcher/phonet-helper down
sleep 7
#
#set cell mode
if [ Z"$3" != Z"" ]; then
  if [ $3 -ge 0 -a $3 -le 2 ]; then 
    dbus-send --system --type=method_call --dest=com.nokia.phone.net /com/nokia/phone/net Phone.Net.set_selected_radio_access_technology byte:$3
    sleep 1
  fi
fi
#
#set connectivity policy
if [ Z"$4" != Z"" ]; then 
  gconftool -s --type list --list-type string /system/osso/connectivity/network_type/auto_connect [$4]
  sleep 1
fi
#
#sudo /sbin/ifconfig phonet0 up
sudo /opt/sim-switcher/phonet-helper up

#give some/infinite time to enter PIN (if SIM requests PIN and only needed for IAP and call forwarding)
#this will wait until cell modem gets online after switching
if [ Z"$5" != Z"" -o Z"$8" != Z"" ]; then
  if [ -n "$verbose" ]; then
    /usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog string:"We need to wait for cell modem to get online ..." uint32:4 string:"ack"
  fi
  if [ Z"$2" != Z"home" ]; then sleep 3; fi
  scount=0
  while [ "`cat /var/run/ssc`" != "online" ] 
  do
    if [ -n "$verbose" ]; then
      /usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteInfoprint string:"... still waiting for cell modem to get online ..."
    fi
    if [ $scount -lt 30 ]; then
      sleep 3
      let scount+=3
    elif [ $scount -lt 60 ]; then
      sleep 5
      let scount+=5
    else  
      sleep 10
      let scount+=10
    fi
    if [ -z "$home_restored" ]; then restore_home "$2"; fi
  done
  if [ -n "$verbose" ]; then
    #/usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog string:"Almost done, we are back online ..." uint32: string:
    /usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteInfoprint string:"Almost done, we are back ONLINE ..."
  fi
fi

#enable IC for specififc IAP
if [ Z"$5" != Z"" ]; then
  sleep 1
  /usr/bin/dbus-send --system --print-reply --type=method_call --dest=com.nokia.icd /com/nokia/icd com.nokia.icd.connect string:"$5" uint32:0
fi

#set call forwarding for new SIM (after change)
if [ Z"$8" != Z"" ]; then
  sleep 5
  if [ $8 -lt 0 ]; then
    let div=$8
    let div*=-1
    /usr/bin/dbus-send --system --print-reply --type=method_call --dest=com.nokia.csd.SS /com/nokia/csd/ss com.nokia.csd.SS.DivertCancel uint32:$div string: uint32:
  else 
    /usr/bin/dbus-send --system --print-reply --type=method_call --dest=com.nokia.csd.SS /com/nokia/csd/ss com.nokia.csd.SS.DivertActivate uint32:$8 string:"$9" uint32:
  fi
fi

#finishing the switch
if [ -z "$home_restored" ]; then
  restore_home $2
fi
#
#get and print SIM2 details
sleep 20
get_SIM_details
MNC2=$MNC
MCC2=$MCC
OP2=$OP
#echo $OP, MNC: $MNC, MCC: $MCC
#
if [ Z"$home_restored" == Z"true" ]; then
  if [ -n "$verbose" ]; then
    /usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog string:"Done, SIM switched and hildon-home restored!
from $OP1, MNC: $MNC1, MCC: $MCC1
to   $OP2, MNC: $MNC2, MCC: $MCC2" uint32: string:
  fi
else
  if [ -n "$verbose" ]; then
    /usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog string:"Done, SIM switched!
from $OP1, MNC: $MNC1, MCC: $MCC1
to   $OP2, MNC: $MNC2, MCC: $MCC2" uint32: string:
  fi
fi

return 0
}


#main
if [ ! -d $confpath/.tmp ]; then mkdir $confpath/.tmp; fi

verbose=""
if [ -n "$2" ]; then
  if [ Z"$2" == Z"-v" -o Z"$2" == Z"--verbose" ]; then
    verbose="true"
  fi
fi

if [ -z "$1" ]
then
  if [ -n "$verbose" ]; then
    /usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog string:"Usage: 
sim-switcher 'name_of_config_file'; #to switch SIM, e.g. 'SIM1'
sim-switcher 'savehome'; #to save plugins/widgets
sim-switcher 'restorehome'; #to restore plugins/widgets
sim-switcher 'break' / 'cancel'; #to break/cancel 
#an ongoing switch (hanging, due to not online)" uint32:0 string:"OK"
  fi
  exit 1
elif [ Z"$1" == Z"savehome" ]
then
  if [ -n "$verbose" ]; then
    /usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteInfoprint string:"Hildon-home plugins saved!" 
  fi
  cp /home/user/.config/hildon-desktop/home.plugins     /home/user/.config/sim-switcher/home.plugins.bkp
  exit 255
elif [ Z"$1" == Z"restorehome" ]
then
  if [ -n "$verbose" ]; then
    /usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteInfoprint string:"Hildon-home plugins will be restored!" 
  fi
  cp /home/user/.config/sim-switcher/home.plugins.bkp /home/user/.config/hildon-desktop/home.plugins
  exit 254
elif [ Z"$1" == Z"onlinecheck" ]
then
  touch $confpath/.onlinecheck
  exit 253
elif [ Z"$1" == Z"noonlinecheck" ]
then
  rm $confpath/.onlinecheck
  exit 252
elif [ Z"$1" == Z"break" -o Z"$1" == Z"cancel" ]
then
  if [ -n "$verbose" ]; then
    /usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteInfoprint string:"... current SIM switching activity will be cancelled ..." 
  fi
  touch $confpath/.tmp/.break
  exit 251
fi

#if [ -z "$(read_config $1)" ] # will not hand back the 'non-local' vars
read_config $1
rc_ret=$?
if [ 0 -eq $rc_ret ]
then
  echo "$1"
  echo "$sim" "$refhome" "$cellmode" "$connpol" "$iap" "$forw_bef" "$forw_n_bef" "$forw_aft" "$forw_n_aft"
  if [ -n "$oper" ]
  then
    set_operator_name "$1" "$oper"
    cso_ret=$?
    if [ 0 -ne $cso_ret ]
    then
      echo set_operator_name returned $cso_ret with msg: $ret_txt
      exit $cso_ret
    fi
  fi
  do_switch "$sim" "$refhome" "$cellmode" "$connpol" "$iap" "$forw_bef" "$forw_n_bef" "$forw_aft" "$forw_n_aft"
  ds_ret=$?
  echo do_switch returned $ds_ret with msg: $ret_txt
  exit $ds_ret
else 
  echo read_config returned $rc_ret with msg: $ret_txt
  exit $rc_ret
fi
#end script
