Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/jarabe/model/network.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/jarabe/model/network.py')
-rw-r--r--src/jarabe/model/network.py389
1 files changed, 343 insertions, 46 deletions
diff --git a/src/jarabe/model/network.py b/src/jarabe/model/network.py
index 3a949da..f265ae4 100644
--- a/src/jarabe/model/network.py
+++ b/src/jarabe/model/network.py
@@ -1,6 +1,6 @@
# Copyright (C) 2008 Red Hat, Inc.
# Copyright (C) 2009 Tomeu Vizoso, Simon Schampijer
-# Copyright (C) 2009 One Laptop per Child
+# Copyright (C) 2009-2010 One Laptop per Child
# Copyright (C) 2009 Paraguay Educa, Martin Abente
# Copyright (C) 2010 Plan Ceibal, Daniel Castelo
#
@@ -18,19 +18,23 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+from gettext import gettext as _
import logging
import os
import time
import dbus
+import dbus.service
import gobject
import ConfigParser
import gconf
+import ctypes
from sugar import dispatch
from sugar import env
from sugar.util import unique_id
+
DEVICE_TYPE_802_3_ETHERNET = 1
DEVICE_TYPE_802_11_WIRELESS = 2
DEVICE_TYPE_GSM_MODEM = 3
@@ -54,6 +58,49 @@ NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0
NM_ACTIVE_CONNECTION_STATE_ACTIVATING = 1
NM_ACTIVE_CONNECTION_STATE_ACTIVATED = 2
+
+NM_DEVICE_STATE_REASON_UNKNOWN = 0
+NM_DEVICE_STATE_REASON_NONE = 1
+NM_DEVICE_STATE_REASON_NOW_MANAGED = 2
+NM_DEVICE_STATE_REASON_NOW_UNMANAGED = 3
+NM_DEVICE_STATE_REASON_CONFIG_FAILED = 4
+NM_DEVICE_STATE_REASON_CONFIG_UNAVAILABLE = 5
+NM_DEVICE_STATE_REASON_CONFIG_EXPIRED = 6
+NM_DEVICE_STATE_REASON_NO_SECRETS = 7
+NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT = 8
+NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED = 9
+NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED = 10
+NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT = 11
+NM_DEVICE_STATE_REASON_PPP_START_FAILED = 12
+NM_DEVICE_STATE_REASON_PPP_DISCONNECT = 13
+NM_DEVICE_STATE_REASON_PPP_FAILED = 14
+NM_DEVICE_STATE_REASON_DHCP_START_FAILED = 15
+NM_DEVICE_STATE_REASON_DHCP_ERROR = 16
+NM_DEVICE_STATE_REASON_DHCP_FAILED = 17
+NM_DEVICE_STATE_REASON_SHARED_START_FAILED = 18
+NM_DEVICE_STATE_REASON_SHARED_FAILED = 19
+NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED = 20
+NM_DEVICE_STATE_REASON_AUTOIP_ERROR = 21
+NM_DEVICE_STATE_REASON_AUTOIP_FAILED = 22
+NM_DEVICE_STATE_REASON_MODEM_BUSY = 23
+NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE = 24
+NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER = 25
+NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT = 26
+NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED = 27
+NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED = 28
+NM_DEVICE_STATE_REASON_GSM_APN_FAILED = 29
+NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING = 30
+NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED = 31
+NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT = 32
+NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED = 33
+NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED = 34
+NM_DEVICE_STATE_REASON_FIRMWARE_MISSING = 35
+NM_DEVICE_STATE_REASON_REMOVED = 36
+NM_DEVICE_STATE_REASON_SLEEPING = 37
+NM_DEVICE_STATE_REASON_CONNECTION_REMOVED = 38
+NM_DEVICE_STATE_REASON_USER_REQUESTED = 39
+NM_DEVICE_STATE_REASON_CARRIER = 40
+
NM_802_11_AP_FLAGS_NONE = 0x00000000
NM_802_11_AP_FLAGS_PRIVACY = 0x00000001
@@ -83,11 +130,16 @@ NM_802_11_DEVICE_CAP_RSN = 0x00000020
SETTINGS_SERVICE = 'org.freedesktop.NetworkManagerUserSettings'
+NM_SERVICE = 'org.freedesktop.NetworkManager'
+NM_IFACE = 'org.freedesktop.NetworkManager'
+NM_PATH = '/org/freedesktop/NetworkManager'
+NM_DEVICE_IFACE = 'org.freedesktop.NetworkManager.Device'
NM_SETTINGS_PATH = '/org/freedesktop/NetworkManagerSettings'
NM_SETTINGS_IFACE = 'org.freedesktop.NetworkManagerSettings'
NM_CONNECTION_IFACE = 'org.freedesktop.NetworkManagerSettings.Connection'
NM_SECRETS_IFACE = 'org.freedesktop.NetworkManagerSettings.Connection.Secrets'
NM_ACCESSPOINT_IFACE = 'org.freedesktop.NetworkManager.AccessPoint'
+NM_ACTIVE_CONN_IFACE = 'org.freedesktop.NetworkManager.Connection.Active'
GSM_USERNAME_PATH = '/desktop/sugar/network/gsm/username'
GSM_PASSWORD_PATH = '/desktop/sugar/network/gsm/password'
@@ -99,6 +151,137 @@ GSM_PUK_PATH = '/desktop/sugar/network/gsm/puk'
_nm_settings = None
_conn_counter = 0
+_nm_device_state_reason_description = None
+
+
+def get_error_by_reason(reason):
+ global _nm_device_state_reason_description
+
+ if _nm_device_state_reason_description is None:
+ _nm_device_state_reason_description = {
+ NM_DEVICE_STATE_REASON_UNKNOWN:
+ _('The reason for the device state change is unknown.'),
+ NM_DEVICE_STATE_REASON_NONE:
+ _('The state change is normal.'),
+ NM_DEVICE_STATE_REASON_NOW_MANAGED:
+ _('The device is now managed.'),
+ NM_DEVICE_STATE_REASON_NOW_UNMANAGED:
+ _('The device is no longer managed.'),
+ NM_DEVICE_STATE_REASON_CONFIG_FAILED:
+ _('The device could not be readied for configuration.'),
+ NM_DEVICE_STATE_REASON_CONFIG_UNAVAILABLE:
+ _('IP configuration could not be reserved '
+ '(no available address, timeout, etc).'),
+ NM_DEVICE_STATE_REASON_CONFIG_EXPIRED:
+ _('The IP configuration is no longer valid.'),
+ NM_DEVICE_STATE_REASON_NO_SECRETS:
+ _('Secrets were required, but not provided.'),
+ NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT:
+ _('The 802.1X supplicant disconnected from '
+ 'the access point or authentication server.'),
+ NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED:
+ _('Configuration of the 802.1X supplicant failed.'),
+ NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED:
+ _('The 802.1X supplicant quit or failed unexpectedly.'),
+ NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT:
+ _('The 802.1X supplicant took too long to authenticate.'),
+ NM_DEVICE_STATE_REASON_PPP_START_FAILED:
+ _('The PPP service failed to start within the allowed time.'),
+ NM_DEVICE_STATE_REASON_PPP_DISCONNECT:
+ _('The PPP service disconnected unexpectedly.'),
+ NM_DEVICE_STATE_REASON_PPP_FAILED:
+ _('The PPP service quit or failed unexpectedly.'),
+ NM_DEVICE_STATE_REASON_DHCP_START_FAILED:
+ _('The DHCP service failed to start within the allowed time.'),
+ NM_DEVICE_STATE_REASON_DHCP_ERROR:
+ _('The DHCP service reported an unexpected error.'),
+ NM_DEVICE_STATE_REASON_DHCP_FAILED:
+ _('The DHCP service quit or failed unexpectedly.'),
+ NM_DEVICE_STATE_REASON_SHARED_START_FAILED:
+ _('The shared connection service failed to start.'),
+ NM_DEVICE_STATE_REASON_SHARED_FAILED:
+ _('The shared connection service quit or failed'
+ ' unexpectedly.'),
+ NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED:
+ _('The AutoIP service failed to start.'),
+ NM_DEVICE_STATE_REASON_AUTOIP_ERROR:
+ _('The AutoIP service reported an unexpected error.'),
+ NM_DEVICE_STATE_REASON_AUTOIP_FAILED:
+ _('The AutoIP service quit or failed unexpectedly.'),
+ NM_DEVICE_STATE_REASON_MODEM_BUSY:
+ _('Dialing failed because the line was busy.'),
+ NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE:
+ _('Dialing failed because there was no dial tone.'),
+ NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER:
+ _('Dialing failed because there was no carrier.'),
+ NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT:
+ _('Dialing timed out.'),
+ NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED:
+ _('Dialing failed.'),
+ NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED:
+ _('Modem initialization failed.'),
+ NM_DEVICE_STATE_REASON_GSM_APN_FAILED:
+ _('Failed to select the specified GSM APN'),
+ NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING:
+ _('Not searching for networks.'),
+ NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED:
+ _('Network registration was denied.'),
+ NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT:
+ _('Network registration timed out.'),
+ NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED:
+ _('Failed to register with the requested GSM network.'),
+ NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED:
+ _('PIN check failed.'),
+ NM_DEVICE_STATE_REASON_FIRMWARE_MISSING:
+ _('Necessary firmware for the device may be missing.'),
+ NM_DEVICE_STATE_REASON_REMOVED:
+ _('The device was removed.'),
+ NM_DEVICE_STATE_REASON_SLEEPING:
+ _('NetworkManager went to sleep.'),
+ NM_DEVICE_STATE_REASON_CONNECTION_REMOVED:
+ _("The device's active connection was removed "
+ "or disappeared."),
+ NM_DEVICE_STATE_REASON_USER_REQUESTED:
+ _('A user or client requested the disconnection.'),
+ NM_DEVICE_STATE_REASON_CARRIER:
+ _("The device's carrier/link changed.")}
+
+ return _nm_device_state_reason_description[reason]
+
+
+def frequency_to_channel(frequency):
+ """Returns the channel matching a given radio channel frequency. If a
+ frequency is not in the dictionary channel 1 will be returned.
+
+ Keyword arguments:
+ frequency -- The radio channel frequency in MHz.
+
+ Return: Channel
+
+ """
+ ftoc = {2412: 1, 2417: 2, 2422: 3, 2427: 4,
+ 2432: 5, 2437: 6, 2442: 7, 2447: 8,
+ 2452: 9, 2457: 10, 2462: 11, 2467: 12,
+ 2472: 13}
+ if frequency not in ftoc:
+ logging.warning('The frequency %s can not be mapped to a channel, '
+ 'defaulting to channel 1.', frequency)
+ return 1
+ return ftoc[frequency]
+
+
+def is_sugar_adhoc_network(ssid):
+ """Checks whether an access point is a sugar Ad-hoc network.
+
+ Keyword arguments:
+ ssid -- Ssid of the access point.
+
+ Return: Boolean
+
+ """
+ return ssid.startswith('Ad-hoc Network')
+
+
class WirelessSecurity(object):
def __init__(self):
self.key_mgmt = None
@@ -118,14 +301,16 @@ class WirelessSecurity(object):
wireless_security['group'] = self.group
return wireless_security
+
class Wireless(object):
- nm_name = "802-11-wireless"
+ nm_name = '802-11-wireless'
def __init__(self):
self.ssid = None
self.security = None
self.mode = None
self.band = None
+ self.channel = None
def get_dict(self):
wireless = {'ssid': self.ssid}
@@ -135,11 +320,13 @@ class Wireless(object):
wireless['mode'] = self.mode
if self.band:
wireless['band'] = self.band
+ if self.channel:
+ wireless['channel'] = self.channel
return wireless
class OlpcMesh(object):
- nm_name = "802-11-olpc-mesh"
+ nm_name = '802-11-olpc-mesh'
def __init__(self, channel, anycast_addr):
self.channel = channel
@@ -147,12 +334,12 @@ class OlpcMesh(object):
def get_dict(self):
ret = {
- "ssid": dbus.ByteArray("olpc-mesh"),
- "channel": self.channel,
+ 'ssid': dbus.ByteArray('olpc-mesh'),
+ 'channel': self.channel,
}
if self.anycast_addr:
- ret["dhcp-anycast-address"] = dbus.ByteArray(self.anycast_addr)
+ ret['dhcp-anycast-address'] = dbus.ByteArray(self.anycast_addr)
return ret
@@ -173,6 +360,7 @@ class Connection(object):
connection['timestamp'] = self.timestamp
return connection
+
class IP4Config(object):
def __init__(self):
self.method = None
@@ -183,6 +371,7 @@ class IP4Config(object):
ip4_config['method'] = self.method
return ip4_config
+
class Serial(object):
def __init__(self):
self.baud = None
@@ -195,6 +384,7 @@ class Serial(object):
return serial
+
class Ppp(object):
def __init__(self):
pass
@@ -203,6 +393,7 @@ class Ppp(object):
ppp = {}
return ppp
+
class Gsm(object):
def __init__(self):
self.apn = None
@@ -221,6 +412,7 @@ class Gsm(object):
return gsm
+
class Settings(object):
def __init__(self, wireless_cfg=None):
self.connection = Connection()
@@ -243,6 +435,7 @@ class Settings(object):
settings['ipv4'] = self.ip4_config.get_dict()
return settings
+
class Secrets(object):
def __init__(self, settings):
self.settings = settings
@@ -268,6 +461,7 @@ class Secrets(object):
return settings
+
class SettingsGsm(object):
def __init__(self):
self.connection = Connection()
@@ -287,22 +481,24 @@ class SettingsGsm(object):
return settings
+
class SecretsGsm(object):
def __init__(self):
self.password = None
self.pin = None
self.puk = None
-
+
def get_dict(self):
secrets = {}
if self.password is not None:
secrets['password'] = self.password
if self.pin is not None:
secrets['pin'] = self.pin
- if self.puk is not None:
+ if self.puk is not None:
secrets['puk'] = self.puk
return {'gsm': secrets}
+
class NMSettings(dbus.service.Object):
def __init__(self):
bus = dbus.SystemBus()
@@ -330,10 +526,19 @@ class NMSettings(dbus.service.Object):
self.secrets_request.send(self, connection=sender,
response=kwargs['response'])
+ def clear_wifi_connections(self):
+ for uuid in self.connections.keys():
+ conn = self.connections[uuid]
+ if conn._settings.connection.type == \
+ NM_CONNECTION_TYPE_802_11_WIRELESS:
+ conn.Removed()
+ self.connections.pop(uuid)
+
+
class SecretsResponse(object):
- ''' Intermediate object to report the secrets from the dialog
+ """Intermediate object to report the secrets from the dialog
back to the connection object and which will inform NM
- '''
+ """
def __init__(self, connection, reply_cb, error_cb):
self._connection = connection
self._reply_cb = reply_cb
@@ -346,6 +551,7 @@ class SecretsResponse(object):
def set_error(self, error):
self._error_cb(error)
+
class NMSettingsConnection(dbus.service.Object):
def __init__(self, path, settings, secrets):
bus = dbus.SystemBus()
@@ -358,27 +564,57 @@ class NMSettingsConnection(dbus.service.Object):
self._settings = settings
self._secrets = secrets
+ @dbus.service.signal(dbus_interface=NM_CONNECTION_IFACE,
+ signature='')
+ def Removed(self):
+ pass
+
+ @dbus.service.signal(dbus_interface=NM_CONNECTION_IFACE,
+ signature='a{sa{sv}}')
+ def Updated(self, settings):
+ pass
+
def set_connected(self):
if self._settings.connection.type == NM_CONNECTION_TYPE_GSM:
self._settings.connection.timestamp = int(time.time())
- else:
- if not self._settings.connection.autoconnect:
- self._settings.connection.autoconnect = True
- self._settings.connection.timestamp = int(time.time())
- if self._settings.connection.type == NM_CONNECTION_TYPE_802_11_WIRELESS:
- self.save()
+ elif not self._settings.connection.autoconnect:
+ self._settings.connection.autoconnect = True
+ self._settings.connection.timestamp = int(time.time())
+ if (self._settings.connection.type ==
+ NM_CONNECTION_TYPE_802_11_WIRELESS):
+ self.Updated(self._settings.get_dict())
+ self.save()
+
+ try:
+ # try to flush resolver cache - SL#1940
+ # ctypes' syntactic sugar does not work
+ # so we must get the func ptr explicitly
+ libc = ctypes.CDLL('libc.so.6')
+ res_init = getattr(libc, '__res_init')
+ res_init(None)
+ except:
+ # pylint: disable=W0702
+ logging.exception('Error calling libc.__res_init')
+
+ def disable_autoconnect(self):
+ if self._settings.connection.type != NM_CONNECTION_TYPE_GSM and \
+ self._settings.connection.autoconnect:
+ self._settings.connection.autoconnect = False
+ self._settings.connection.timestamp = None
+ self.Updated(self._settings.get_dict())
+ self.save()
def set_secrets(self, secrets):
self._secrets = secrets
- if self._settings.connection.type == NM_CONNECTION_TYPE_802_11_WIRELESS:
+ if self._settings.connection.type == \
+ NM_CONNECTION_TYPE_802_11_WIRELESS:
self.save()
def get_settings(self):
return self._settings
def save(self):
- profile_path = env.get_profile_path()
- config_path = os.path.join(profile_path, 'nm', 'connections.cfg')
+ config_path = _get_wifi_connections_path()
config = ConfigParser.ConfigParser()
try:
@@ -443,22 +679,31 @@ class NMSettingsConnection(dbus.service.Object):
in_signature='sasb', out_signature='a{sa{sv}}')
def GetSecrets(self, setting_name, hints, request_new, reply, error):
logging.debug('Secrets requested for connection %s request_new=%s',
- self.path, request_new)
- if request_new or self._secrets is None:
- # request_new is for example the case when the pw on the AP changes
- response = SecretsResponse(self, reply, error)
- try:
- self.secrets_request.send(self, response=response)
- except Exception:
- logging.exception('Error requesting the secrets via dialog')
+ self.path, request_new)
+ if self._settings.connection.type is not NM_CONNECTION_TYPE_GSM:
+ if request_new or self._secrets is None:
+ # request_new is for example the case when the pw on the AP
+ # changes
+ response = SecretsResponse(self, reply, error)
+ try:
+ self.secrets_request.send(self, response=response)
+ except Exception:
+ logging.exception('Error requesting the secrets via'
+ ' dialog')
+ else:
+ reply(self._secrets.get_dict())
else:
- reply(self._secrets.get_dict())
+ if not request_new:
+ reply(self._secrets.get_dict())
+ else:
+ raise Exception('The stored GSM secret has already been'
+ ' supplied')
class AccessPoint(gobject.GObject):
__gsignals__ = {
'props-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
- ([gobject.TYPE_PYOBJECT]))
+ ([gobject.TYPE_PYOBJECT])),
}
def __init__(self, device, model):
@@ -475,10 +720,10 @@ class AccessPoint(gobject.GObject):
self.wpa_flags = 0
self.rsn_flags = 0
self.mode = 0
+ self.channel = 0
def initialize(self):
- model_props = dbus.Interface(self.model,
- 'org.freedesktop.DBus.Properties')
+ model_props = dbus.Interface(self.model, dbus.PROPERTIES_IFACE)
model_props.GetAll(NM_ACCESSPOINT_IFACE, byte_arrays=True,
reply_handler=self._ap_properties_changed_cb,
error_handler=self._get_all_props_error_cb)
@@ -523,7 +768,7 @@ class AccessPoint(gobject.GObject):
else:
fl |= 1 << 6
- hashstr = str(fl) + "@" + self.name
+ hashstr = str(fl) + '@' + self.name
return hash(hashstr)
def _update_properties(self, properties):
@@ -544,6 +789,9 @@ class AccessPoint(gobject.GObject):
self.rsn_flags = properties['RsnFlags']
if 'Mode' in properties:
self.mode = properties['Mode']
+ if 'Frequency' in properties:
+ self.channel = frequency_to_channel(properties['Frequency'])
+
self._initialized = True
self.emit('props-changed', old_hash)
@@ -559,6 +807,7 @@ class AccessPoint(gobject.GObject):
path=self.model.object_path,
dbus_interface=NM_ACCESSPOINT_IFACE)
+
def get_settings():
global _nm_settings
if _nm_settings is None:
@@ -569,17 +818,20 @@ def get_settings():
load_connections()
return _nm_settings
+
def find_connection_by_ssid(ssid):
connections = get_settings().connections
for conn_index in connections:
connection = connections[conn_index]
- if connection._settings.connection.type == NM_CONNECTION_TYPE_802_11_WIRELESS:
- if connection._settings.wireless.ssid == ssid:
- return connection
+ if connection._settings.connection.type == \
+ NM_CONNECTION_TYPE_802_11_WIRELESS and \
+ connection._settings.wireless.ssid == ssid:
+ return connection
return None
+
def add_connection(uuid, settings, secrets=None):
global _conn_counter
@@ -590,19 +842,26 @@ def add_connection(uuid, settings, secrets=None):
_nm_settings.add_connection(uuid, conn)
return conn
-def load_wifi_connections():
+
+def _get_wifi_connections_path():
profile_path = env.get_profile_path()
- config_path = os.path.join(profile_path, 'nm', 'connections.cfg')
+ return os.path.join(profile_path, 'nm', 'connections.cfg')
- config = ConfigParser.ConfigParser()
+
+def _create_wifi_connections(config_path):
+ if not os.path.exists(os.path.dirname(config_path)):
+ os.makedirs(os.path.dirname(config_path), 0755)
+ f = open(config_path, 'w')
+ f.close()
+
+
+def load_wifi_connections():
+ config_path = _get_wifi_connections_path()
if not os.path.exists(config_path):
- if not os.path.exists(os.path.dirname(config_path)):
- os.makedirs(os.path.dirname(config_path), 0755)
- f = open(config_path, 'w')
- config.write(f)
- f.close()
+ _create_wifi_connections(config_path)
+ config = ConfigParser.ConfigParser()
try:
if not config.read(config_path):
logging.error('Error reading the nm config file')
@@ -672,10 +931,10 @@ def load_gsm_connection():
if username and number and apn:
settings = SettingsGsm()
- settings.gsm.username = username
+ settings.gsm.username = username
settings.gsm.number = number
settings.gsm.apn = apn
-
+
secrets = SecretsGsm()
secrets.pin = pin
secrets.puk = puk
@@ -693,12 +952,14 @@ def load_gsm_connection():
except Exception:
logging.exception('Error adding gsm connection to NMSettings.')
else:
- logging.exception("No gsm connection was set in GConf.")
+ logging.warning('No gsm connection was set in GConf.')
+
def load_connections():
load_wifi_connections()
load_gsm_connection()
+
def find_gsm_connection():
connections = get_settings().connections
@@ -708,3 +969,39 @@ def find_gsm_connection():
logging.debug('There is no gsm connection in the NMSettings.')
return None
+
+
+def have_wifi_connections():
+ return bool(get_settings().connections)
+
+
+def clear_wifi_connections():
+ if _nm_settings is not None:
+ _nm_settings.clear_wifi_connections()
+
+ config_path = _get_wifi_connections_path()
+ _create_wifi_connections(config_path)
+
+
+def disconnect_access_points(ap_paths):
+ """
+ Disconnect all devices connected to any of the given access points.
+ """
+ bus = dbus.SystemBus()
+ netmgr_obj = bus.get_object(NM_SERVICE, NM_PATH)
+ netmgr = dbus.Interface(netmgr_obj, NM_IFACE)
+ netmgr_props = dbus.Interface(netmgr, dbus.PROPERTIES_IFACE)
+ active_connection_paths = netmgr_props.Get(NM_IFACE, 'ActiveConnections')
+
+ for conn_path in active_connection_paths:
+ conn_obj = bus.get_object(NM_IFACE, conn_path)
+ conn_props = dbus.Interface(conn_obj, dbus.PROPERTIES_IFACE)
+ ap_path = conn_props.Get(NM_ACTIVE_CONN_IFACE, 'SpecificObject')
+ if ap_path == '/' or ap_path not in ap_paths:
+ continue
+
+ dev_paths = conn_props.Get(NM_ACTIVE_CONN_IFACE, 'Devices')
+ for dev_path in dev_paths:
+ dev_obj = bus.get_object(NM_SERVICE, dev_path)
+ dev = dbus.Interface(dev_obj, NM_DEVICE_IFACE)
+ dev.Disconnect()