Sunday, December 12, 2010

Network-manager auto-reconnect [SOLVED]

Many times I had the following message from my network manager in Ubuntu: GSM network Disconnected — you are now offline. It was not possible to reconnect again with Network-manager, for sure I checked "connect automaticly" in its option, but that didn't help. The only solution was to unplug my USB modem and plug it in again to my pc. It was very annoying.

I have found many errors related to this problem in logs.

First, nm-applet gives

** (nm-applet:32060): WARNING **: Error in getting active connection 'Vpn' property: (19) Method "Get" with signature "ss" on interface "org.freedesktop.DBus.Properties" doesn't exist
** (nm-applet:32060): WARNING **: _nm_object_array_demarshal: couldn't create object for /org/freedesktop/NetworkManager/ActiveConnection/56


Second, dmesg gives

[253846.006408] option: option_instat_callback: error -108
[253846.006795] option1 ttyUSB0: GSM modem (1-port) converter now disconnected from ttyUSB0
[253846.010641] option 2-3:1.0: device disconnected


There are errors from /var/log/messages

Dec 10 03:32:49 ubuntu-main pppd[5158]: LCP terminated by peer
Dec 10 03:32:49 ubuntu-main pppd[5158]: Connect time 26.2 minutes.
Dec 10 03:32:49 ubuntu-main pppd[5158]: Sent 857127 bytes, received 3813495 bytes.
Dec 10 03:32:49 ubuntu-main pppd[5158]: Modem hangup
Dec 10 03:32:49 ubuntu-main pppd[5158]: Connection terminated.


It seems that my Internet service provider (ISP) terminates the connection and network-manager is not capable to make auto-reconnection.

Here is a solution I have found.

Try the to run the following two lines it the terminal:


sudo killall modem-manager nm-applet
modem-manager & nm-applet


If you can reconnect after that - this solution is for you.
In fact, this is just a restart for modem-manager and nm-applet.

This could be the end but I decided to write a script to make it automatically cause due to my ISP I could be disconnected many time per day.

I wrote the script in python that check Internet connection every minute and run the above mentioned commands to make reconnection if its necessary. Here is the script.

#!/usr/bin/env python

"""
auto-reconnect.py - a code to accomplish auto reconnection to the internet
source: http://best-ubuntu-notebook.blogspot.com/
python version '2.6.5'

"""

import urllib2,os,time

#loading from a file
def download_lines(name):
  inputfile = open(name, 'r') # open file for reading
  lines = inputfile.readlines()
  inputfile.close()
  return lines[0].replace('\n','')

#checking function
def check_connection (site):

  print 'Checking connection...'

  req = urllib2.Request(site)

  flag=False

  try:
    u = urllib2.urlopen(req)
  except urllib2.URLError, e:
    print 'URLError'
  except urllib2.HTTPError, e:
    print 'HTTPError'
  except Exception, e:
    print 'Exception'
  else:
    print
    print 'We are connected!'
    flag=True
    
  return flag

delay=60 #delay in seconds to give nm-applet the possibility to make a connection
big_delay=60 #time between Internet connection checking

directive_path='...'
path_to_kill_modem_manager_script='...'

test_site='http://www.microsoft.com/'

directive=download_lines(directive_path)

if directive=='continue':
  flag_continue=True
else:
  flag_continue=False

while flag_continue:

  trial=0

  flag=check_connection(test_site)

  while not flag:

    trial=trial+1

    print
    print 'Trial number: ', trial

    os.system('sudo '+path_to_kill_modem_manager_script)

    os.system('killall nm-applet')
    os.system('modem-manager')

    os.system('nohup nm-applet &')

    if not flag:
      print 'Wait ',delay,'sec before cheking'
      time.sleep(delay)

    flag=check_connection(test_site)

    directive=download_lines(directive_path)
    
    if directive=='continue':
      flag_continue=True
    else:
      print 'Exit'
      flag_continue=False
      flag=True

  if flag_continue:
    print 'It seems that we are online, waiting ',big_delay,'sec before the next checking of the Internet connection'
    time.sleep(big_delay)


Additionally you have to specify the path to two files in variables directive_path and path_to_kill_modem_manager_script. First file (name it as directive) has to have a word continue if you want this script to run continuously. The second (name it as kill_modem_manager_script, respectively) has to have the following content:

#!/bin/bash
killall modem-manager


It is clear that the last is a bash script to 'kill' modem-manager. You have to give to yourself a permission to run this script as the root without entering a password. For this you have to run in the terminal
sudo visudo

and add the following line:
username ALL=NOPASSWD:

Here you have to substitute your username there and also to add the same path as in the variable path_to_kill_modem_manager_script after ALL=NOPASSWD:. And of course you have to add execute permission to kill_modem_manager_script.

P.S. I am sure that there are some much simpler solutions, but the proposed script is working and and working very well. Anyway, you are welcome to comment it.