Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details:
- #
- # Copyright (C) 2008 Novell, Inc.
- # Copyright (C) 2009 Red Hat, Inc.
- # Copyright (C) 2011 Markus Rothe <markus@unixforces.net>
- #
- # based on mm-test.py from ModemManager
- #
- import argparse
- import sys
- import dbus
- import time
- import os
- import string
- import subprocess
- import socket
- DEFAULT_APN='internet.eplus.de'
- DEFAULT_USER='blau'
- DEFAULT_PASS='blau'
- DBUS_INTERFACE_PROPERTIES='org.freedesktop.DBus.Properties'
- MM_DBUS_SERVICE='org.freedesktop.ModemManager'
- MM_DBUS_PATH='/org/freedesktop/ModemManager'
- MM_DBUS_INTERFACE='org.freedesktop.ModemManager'
- MM_DBUS_INTERFACE_MODEM='org.freedesktop.ModemManager.Modem'
- MM_DBUS_INTERFACE_MODEM_CDMA='org.freedesktop.ModemManager.Modem.Cdma'
- MM_DBUS_INTERFACE_MODEM_GSM_CARD='org.freedesktop.ModemManager.Modem.Gsm.Card'
- MM_DBUS_INTERFACE_MODEM_GSM_NETWORK='org.freedesktop.ModemManager.Modem.Gsm.Network'
- MM_DBUS_INTERFACE_MODEM_SIMPLE='org.freedesktop.ModemManager.Modem.Simple'
- def get_cdma_band_class(band_class):
- if band_class == 1:
- return "800MHz"
- elif band_class == 2:
- return "1900MHz"
- else:
- return "Unknown"
- def get_reg_state(state):
- if state == 1:
- return "registered (roaming unknown)"
- elif state == 2:
- return "registered on home network"
- elif state == 3:
- return "registered on roaming network"
- else:
- return "unknown"
- def cdma_inspect(proxy, show_private):
- cdma = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM_CDMA)
- esn = "<private>"
- if show_private:
- try:
- esn = cdma.GetEsn()
- except dbus.exceptions.DBusException:
- esn = "<unavailable>"
- print ""
- print "ESN: %s" % esn
- try:
- (cdma_1x_state, evdo_state) = cdma.GetRegistrationState()
- print "1x State: %s" % get_reg_state (cdma_1x_state)
- print "EVDO State: %s" % get_reg_state (evdo_state)
- except dbus.exceptions.DBusException, e:
- print "Error reading registration state: %s" % e
- try:
- quality = cdma.GetSignalQuality()
- print "Signal quality: %d" % quality
- except dbus.exceptions.DBusException, e:
- print "Error reading signal quality: %s" % e
- try:
- info = cdma.GetServingSystem()
- print "Class: %s" % get_cdma_band_class(info[0])
- print "Band: %s" % info[1]
- print "SID: %d" % info[2]
- except dbus.exceptions.DBusException, e:
- print "Error reading serving system: %s" % e
- def cdma_connect(proxy, user, password):
- # Modem.Simple interface
- simple = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM_SIMPLE)
- try:
- simple.Connect({'number':"#777"}, timeout=92)
- print "\nConnected!"
- return True
- except Exception, e:
- print "Error connecting: %s" % e
- return False
- def get_gsm_network_mode(modem):
- mode = modem.GetNetworkMode()
- if mode == 0x0:
- mode = "Unknown"
- elif mode == 0x1:
- mode = "Any"
- elif mode == 0x2:
- mode = "GPRS"
- elif mode == 0x4:
- mode = "EDGE"
- elif mode == 0x8:
- mode = "UMTS"
- elif mode == 0x10:
- mode = "HSDPA"
- elif mode == 0x20:
- mode = "2G Preferred"
- elif mode == 0x40:
- mode = "3G Preferred"
- elif mode == 0x80:
- mode = "2G Only"
- elif mode == 0x100:
- mode = "3G Only"
- elif mode == 0x200:
- mode = "HSUPA"
- elif mode == 0x400:
- mode = "HSPA"
- else:
- mode = "(Unknown)"
- print "Mode: %s" % mode
- def get_gsm_band(modem):
- band = modem.GetBand()
- if band == 0x0:
- band = "Unknown"
- elif band == 0x1:
- band = "Any"
- elif band == 0x2:
- band = "EGSM (900 MHz)"
- elif band == 0x4:
- band = "DCS (1800 MHz)"
- elif band == 0x8:
- band = "PCS (1900 MHz)"
- elif band == 0x10:
- band = "G850 (850 MHz)"
- elif band == 0x20:
- band = "U2100 (WCSMA 2100 MHZ, Class I)"
- elif band == 0x40:
- band = "U1700 (WCDMA 3GPP UMTS1800 MHz, Class III)"
- elif band == 0x80:
- band = "17IV (WCDMA 3GPP AWS 1700/2100 MHz, Class IV)"
- elif band == 0x100:
- band = "U800 (WCDMA 3GPP UMTS800 MHz, Class VI)"
- elif band == 0x200:
- band = "U850 (WCDMA 3GPP UMT850 MHz, Class V)"
- elif band == 0x400:
- band = "U900 (WCDMA 3GPP UMTS900 MHz, Class VIII)"
- elif band == 0x800:
- band = "U17IX (WCDMA 3GPP UMTS MHz, Class IX)"
- else:
- band = "(invalid)"
- print "Band: %s" % band
- def gsm_inspect(proxy, show_private, do_scan):
- # Gsm.Card interface
- card = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM_GSM_CARD)
- imei = "<private>"
- imsi = "<private>"
- if show_private:
- try:
- imei = card.GetImei()
- except dbus.exceptions.DBusException:
- imei = "<unavailable>"
- try:
- imsi = card.GetImsi()
- except dbus.exceptions.DBusException:
- imsi = "<unavailable>"
- print "IMEI: %s" % imei
- print "IMSI: %s" % imsi
- # Gsm.Network interface
- net = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM_GSM_NETWORK)
- try:
- quality = net.GetSignalQuality()
- print "Signal quality: %d" % quality
- except dbus.exceptions.DBusException, e:
- print "Error reading signal quality: %s" % e
- if not do_scan:
- return
- print "Scanning..."
- try:
- results = net.Scan(timeout=120)
- except dbus.exceptions.DBusException, e:
- print "Error scanning: %s" % e
- results = {}
- for r in results:
- status = r['status']
- if status == "1":
- status = "available"
- elif status == "2":
- status = "current"
- elif status == "3":
- status = "forbidden"
- else:
- status = "(Unknown)"
- access_tech = ""
- try:
- access_tech_num = r['access-tech']
- if access_tech_num == "0":
- access_tech = "(GSM)"
- elif access_tech_num == "1":
- access_tech = "(Compact GSM)"
- elif access_tech_num == "2":
- access_tech = "(UMTS)"
- elif access_tech_num == "3":
- access_tech = "(EDGE)"
- elif access_tech_num == "4":
- access_tech = "(HSDPA)"
- elif access_tech_num == "5":
- access_tech = "(HSUPA)"
- elif access_tech_num == "6":
- access_tech = "(HSPA)"
- except KeyError:
- pass
- if r.has_key('operator-long') and len(r['operator-long']):
- print "%s: %s %s" % (r['operator-long'], status, access_tech)
- elif r.has_key('operator-short') and len(r['operator-short']):
- print "%s: %s %s" % (r['operator-short'], status, access_tech)
- else:
- print "%s: %s %s" % (r['operator-num'], status, access_tech)
- def gsm_connect(proxy, apn, user, password):
- # Modem.Simple interface
- simple = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM_SIMPLE)
- try:
- opts = {'number':"*99#"}
- if apn is not None:
- opts['apn'] = apn
- if user is not None:
- opts['username'] = user
- if password is not None:
- opts['password'] = password
- simple.Connect(opts, timeout=120)
- print "\nConnected!"
- return True
- except Exception, e:
- print "Error connecting: %s" % e
- return False
- def pppd_find():
- paths = ["/usr/local/sbin/pppd", "/usr/sbin/pppd", "/sbin/pppd"]
- for p in paths:
- if os.path.exists(p):
- return p
- return None
- def ppp_start(device, user, password, tmpfile):
- path = pppd_find()
- if not path:
- return None
- args = [path]
- args += ["defaultroute"]
- args += ["nodetach"]
- args += ["lock"]
- if user:
- args += ["user"]
- args += [user]
- args += ["noipdefault"]
- args += ["115200"]
- args += ["noauth"]
- args += ["crtscts"]
- args += ["usepeerdns"]
- args += ["ipparam"]
- ipparam = ""
- if user:
- ipparam += user
- ipparam += "+"
- if password:
- ipparam += password
- ipparam += "+"
- ipparam += tmpfile
- args += [ipparam]
- # args += ["plugin"]
- # args += ["mm-test-pppd-plugin.so"]
- args += [device]
- return subprocess.Popen(args, close_fds=True, cwd="/", env={})
- def ppp_wait(p, tmpfile):
- i = 0
- while p.poll() == None and i < 30:
- time.sleep(1)
- if os.path.exists(tmpfile):
- f = open(tmpfile, 'r')
- stuff = f.read(500)
- idx = string.find(stuff, "DONE")
- f.close()
- if idx >= 0:
- return True
- i += 1
- return False
- def ppp_stop(p):
- import signal
- p.send_signal(signal.SIGTERM)
- p.wait()
- def ntop_helper(ip):
- ip = socket.ntohl(ip)
- n1 = ip >> 24 & 0xFF
- n2 = ip >> 16 & 0xFF
- n3 = ip >> 8 & 0xFF
- n4 = ip & 0xFF
- a = "%c%c%c%c" % (n1, n2, n3, n4)
- return socket.inet_ntop(socket.AF_INET, a)
- def static_start(iface, modem):
- (addr_num, dns1_num, dns2_num, dns3_num) = modem.GetIP4Config()
- addr = ntop_helper(addr_num)
- dns1 = ntop_helper(dns1_num)
- dns2 = ntop_helper(dns2_num)
- configure_iface(iface, addr, 0, dns1, dns2)
- def down_iface(iface):
- ip = ["ip", "addr", "flush", "dev", iface]
- print " ".join(ip)
- subprocess.call(ip)
- ip = ["ip", "link", "set", iface, "down"]
- print " ".join(ip)
- subprocess.call(ip)
- def configure_iface(iface, addr, gw, dns1, dns2):
- print "\n\n******************************"
- print "iface: %s" % iface
- print "addr: %s" % addr
- print "gw: %s" % gw
- print "dns1: %s" % dns1
- print "dns2: %s" % dns2
- ifconfig = ["ifconfig", iface, "%s/32" % addr]
- if gw != 0:
- ifconfig += ["pointopoint", gw]
- print " ".join(ifconfig)
- print "\n******************************\n"
- subprocess.call(ifconfig)
- def file_configure_iface(tmpfile):
- addr = None
- gw = None
- iface = None
- dns1 = None
- dns2 = None
- f = open(tmpfile, 'r')
- lines = f.readlines()
- for l in lines:
- if l.startswith("addr"):
- addr = l[len("addr"):].strip()
- if l.startswith("gateway"):
- gw = l[len("gateway"):].strip()
- if l.startswith("iface"):
- iface = l[len("iface"):].strip()
- if l.startswith("dns1"):
- dns1 = l[len("dns1"):].strip()
- if l.startswith("dns2"):
- dns2 = l[len("dns2"):].strip()
- f.close()
- configure_iface(iface, addr, gw, dns1, dns2)
- return iface
- def try_ping(iface):
- cmd = ["ping", "-I", iface, "-c", "4", "-i", "3", "-w", "20", "4.2.2.1"]
- print " ".join(cmd)
- retcode = subprocess.call(cmd)
- if retcode != 0:
- print "PING: failed"
- else:
- print "PING: success"
- def connect(args):
- bus = dbus.SystemBus()
- # Get available modems:
- manager_proxy = bus.get_object('org.freedesktop.ModemManager', '/org/freedesktop/ModemManager')
- manager_iface = dbus.Interface(manager_proxy, dbus_interface='org.freedesktop.ModemManager')
- modems = manager_iface.EnumerateDevices()
- if not modems:
- print "No modems found"
- sys.exit(1)
- for m in modems:
- connect_success = False
- data_device = None
- proxy = bus.get_object(MM_DBUS_SERVICE, m)
- # Properties
- props_iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.DBus.Properties')
- type = props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Type')
- if type == 1:
- print "GSM modem"
- elif type == 2:
- print "CDMA modem"
- else:
- print "Invalid modem type: %d" % type
- print "Driver: '%s'" % (props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Driver'))
- print "Modem device: '%s'" % (props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'MasterDevice'))
- data_device = props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Device')
- print "Data device: '%s'" % data_device
- # Modem interface
- modem = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM)
- try:
- modem.Enable(True)
- except dbus.exceptions.DBusException, e:
- print "Error enabling modem: %s" % e
- sys.exit(1)
- info = modem.GetInfo()
- print "Vendor: %s" % info[0]
- print "Model: %s" % info[1]
- print "Version: %s" % info[2]
- if type == 1:
- gsm_inspect(proxy, args.show_private, False)
- connect_success = gsm_connect(proxy, args.apn, args.username, args.password)
- elif type == 2:
- cdma_inspect(proxy, args.show_private)
- connect_success = cdma_connect(proxy, args.username, args.password)
- print
- if connect_success:
- tmpfile = "/tmp/mm-test-%d.tmp" % os.getpid()
- success = False
- try:
- ip_method = props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'IpMethod')
- if ip_method == 0:
- # ppp
- p = ppp_start(data_device, args.username, args.password, tmpfile)
- if ppp_wait(p, tmpfile):
- data_device = file_configure_iface(tmpfile)
- success = True
- elif ip_method == 1:
- # static
- if os.geteuid() != 0:
- print "You probably want to be root"
- sys.exit(1)
- static_start(data_device, modem)
- success = True
- elif ip_method == 2:
- # dhcp
- pass
- except Exception, e:
- print "Error setting up IP: %s" % e
- def scan(args):
- print "Connecting..."
- bus = dbus.SystemBus()
- # Get available modems:
- manager_proxy = bus.get_object('org.freedesktop.ModemManager', '/org/freedesktop/ModemManager')
- manager_iface = dbus.Interface(manager_proxy, dbus_interface='org.freedesktop.ModemManager')
- modems = manager_iface.EnumerateDevices()
- if not modems:
- print "No modems found"
- sys.exit(1)
- for m in modems:
- connect_success = False
- data_device = None
- proxy = bus.get_object(MM_DBUS_SERVICE, m)
- # Properties
- props_iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.DBus.Properties')
- type = props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Type')
- if type == 1:
- print "GSM modem"
- elif type == 2:
- print "CDMA modem"
- else:
- print "Invalid modem type: %d" % type
- print "Driver: '%s'" % (props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Driver'))
- print "Modem device: '%s'" % (props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'MasterDevice'))
- data_device = props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Device')
- print "Data device: '%s'" % data_device
- # Modem interface
- modem = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM)
- try:
- modem.Enable(True)
- except dbus.exceptions.DBusException, e:
- print "Error enabling modem: %s" % e
- sys.exit(1)
- info = modem.GetInfo()
- print "Vendor: %s" % info[0]
- print "Model: %s" % info[1]
- print "Version: %s" % info[2]
- if type == 1:
- gsm_inspect(proxy, args.show_private, True)
- elif type == 2:
- cdma_inspect(proxy, args.show_private)
- print "Sorry, no scanning available with CDMA"
- print
- def disconnect(args):
- print "Disconnecting..."
- bus = dbus.SystemBus()
- # Get available modems:
- manager_proxy = bus.get_object('org.freedesktop.ModemManager', '/org/freedesktop/ModemManager')
- manager_iface = dbus.Interface(manager_proxy, dbus_interface='org.freedesktop.ModemManager')
- modems = manager_iface.EnumerateDevices()
- if not modems:
- print "No modems found"
- sys.exit(1)
- for m in modems:
- connect_success = False
- data_device = None
- proxy = bus.get_object(MM_DBUS_SERVICE, m)
- # Properties
- props_iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.DBus.Properties')
- type = props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Type')
- if type == 1:
- print "GSM modem"
- elif type == 2:
- print "CDMA modem"
- else:
- print "Invalid modem type: %d" % type
- print "Driver: '%s'" % (props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Driver'))
- print "Modem device: '%s'" % (props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'MasterDevice'))
- data_device = props_iface.Get(MM_DBUS_INTERFACE_MODEM, 'Device')
- print "Data device: '%s'" % data_device
- # Modem interface
- modem = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM)
- # try:
- # if ip_method == 0:
- # ppp_stop(p)
- # try:
- # os.remove(tmpfile)
- # except:
- # pass
- # elif ip_method == 1:
- # # static
- # down_iface(data_device)
- # elif ip_method == 2:
- # # dhcp
- # down_iface(data_device)
- #
- # modem.Disconnect()
- # except Exception, e:
- # print "Error tearing down IP: %s" % e
- #
- #
- modem.Disconnect()
- time.sleep(5)
- modem.Enable(False)
- def main():
- #
- # option parsing
- #
- parser = argparse.ArgumentParser(description='Set up a connection using ModemManager.')
- subparsers = parser.add_subparsers()
- common_parser = argparse.ArgumentParser(add_help=False)
- common_parser.add_argument('--show-private', '-s', action='store_true', help='Show private data (e.g. IMSI)')
- # create the parser for the "connect" command
- parser_connect = subparsers.add_parser('connect', parents=[common_parser], help='Open the connection')
- parser_connect.add_argument('--apn', '-a', type=str, default=DEFAULT_APN, help='Access Point Name')
- parser_connect.add_argument('--username', '--user', '-u', type=str, default=DEFAULT_USER, help='Username for APN')
- parser_connect.add_argument('--password', '--pass', '-p', type=str, default=DEFAULT_PASS, help='Password for APN')
- parser_connect.set_defaults(func=connect)
- # create the parser for the "disconnect" command
- parser_disconnect = subparsers.add_parser('disconnect', help='Close the connection')
- parser_disconnect.set_defaults(func=disconnect)
- # create the parser for the "scan" command
- parser_scan = subparsers.add_parser('scan', parents=[common_parser], help='Do a network scan')
- parser_scan.set_defaults(func=scan)
- args = parser.parse_args()
- args.func(args)
- if __name__ == '__main__':
- main()
Add Comment
Please, Sign In to add comment