diff options
author | Martin Abente <martin.abente.lahaye@gmail.org> | 2010-11-01 17:23:51 (GMT) |
---|---|---|
committer | Anish Mangal <anish@sugarlabs.org> | 2011-08-26 05:55:55 (GMT) |
commit | 2b37c6a1b060c58cedd143bc17cfd66f5962c90c (patch) | |
tree | 196daf2aa9d2ba094e70a648d88ee74b185a220c | |
parent | 259c6f294cf3a22c6644b965fb9ec32ccb92db04 (diff) |
Share 3g connection
dextrose backport
Signed-off-by: Anish Mangal <anish@sugarlabs.org>
-rw-r--r-- | extensions/deviceicon/network.py | 177 |
1 files changed, 167 insertions, 10 deletions
diff --git a/extensions/deviceicon/network.py b/extensions/deviceicon/network.py index d39ced9..60c8a32 100644 --- a/extensions/deviceicon/network.py +++ b/extensions/deviceicon/network.py @@ -23,6 +23,7 @@ import logging import hashlib import socket import struct +import random import re import datetime import time @@ -62,6 +63,7 @@ _NM_SERIAL_IFACE = 'org.freedesktop.NetworkManager.Device.Serial' _NM_OLPC_MESH_IFACE = 'org.freedesktop.NetworkManager.Device.OlpcMesh' _NM_ACCESSPOINT_IFACE = 'org.freedesktop.NetworkManager.AccessPoint' _NM_ACTIVE_CONN_IFACE = 'org.freedesktop.NetworkManager.Connection.Active' +_NM_OBJ_PROPERTIES = 'org.freedesktop.DBus.Properties' _GSM_STATE_NOT_READY = 0 _GSM_STATE_DISCONNECTED = 1 @@ -69,6 +71,11 @@ _GSM_STATE_CONNECTING = 2 _GSM_STATE_CONNECTED = 3 _GSM_STATE_FAILED = 4 +_GSM_SHARING_PRIVATE = 0 +_GSM_SHARING_TRYING = 1 +_GSM_SHARING_NEIGHBORHOOD = 2 + +_GSM_SHARING_CHANNELS = [2,3,4,5,7,8,9,10,12,13] class WirelessPalette(Palette): __gtype_name__ = 'SugarWirelessPalette' @@ -209,6 +216,10 @@ class GsmPalette(Palette): gobject.TYPE_NONE, ([])), 'gsm-disconnect' : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), + 'gsm-private' : (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([])), + 'gsm-neighborhood' : (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([])) } def __init__(self): @@ -216,12 +227,17 @@ class GsmPalette(Palette): Palette.__init__(self, label=_('Wireless modem')) self._current_state = None self._alert = False + self._sharing_state = _GSM_SHARING_PRIVATE self._toggle_state_item = MenuItem('') self._toggle_state_item.connect('activate', self.__toggle_state_cb) self.menu.append(self._toggle_state_item) self._toggle_state_item.show() + self._sharing_toggle_item = MenuItem('') + self._sharing_toggle_item.connect('activate', self.__sharing_toggle_cb) + self.menu.append(self._sharing_toggle_item) + self.info_box = gtk.VBox() self.error_description_label = gtk.Label("") @@ -302,6 +318,9 @@ class GsmPalette(Palette): icon = Icon(icon_name='media-eject', \ icon_size=gtk.ICON_SIZE_MENU) self._toggle_state_item.set_image(icon) + self.sharing_update_text() + self._sharing_toggle_item.show() + return elif self._current_state == _GSM_STATE_FAILED: message_error = self._get_error_by_nm_reason(reason) @@ -310,6 +329,8 @@ class GsmPalette(Palette): else: raise ValueError('Invalid GSM state while updating label and ' \ 'text, %s' % str(self._current_state)) + + self._sharing_toggle_item.hide() def add_alert(self, title, message): self._alert = True @@ -366,6 +387,38 @@ class GsmPalette(Palette): else: raise ValueError('Invalid GSM state while emitting signal, %s' % \ str(self._current_state)) + + def sharing_update_text(self): + if self._sharing_state == _GSM_SHARING_PRIVATE: + self._sharing_toggle_item.get_child().set_label(_('Private')) + icon = Icon(icon_name='zoom-home', icon_size=gtk.ICON_SIZE_MENU) + self._sharing_toggle_item.set_image(icon) + + elif self._sharing_state == _GSM_SHARING_TRYING: + self._sharing_toggle_item.get_child().set_label(_('Please wait...')) + + elif self._sharing_state == _GSM_SHARING_NEIGHBORHOOD: + self._sharing_toggle_item.get_child().set_label(_('My Neighborhood')) + icon = Icon(icon_name='zoom-neighborhood', icon_size=gtk.ICON_SIZE_MENU) + self._sharing_toggle_item.set_image(icon) + + else: + raise ValueError('Invalid GSM sharing state while updating, %s' % \ + str(self._sharing_state)) + + def __sharing_toggle_cb(self, menuitem): + if self._sharing_state == _GSM_SHARING_PRIVATE: + self.emit('gsm-neighborhood') + + elif self._sharing_state == _GSM_SHARING_TRYING: + pass + + elif self._sharing_state == _GSM_SHARING_NEIGHBORHOOD: + self.emit('gsm-private') + + else: + raise ValueError('Invalid GSM sharing state, %s' % \ + str(self._sharing_state)) class WirelessDeviceView(ToolButton): @@ -523,8 +576,16 @@ class WirelessDeviceView(ToolButton): else: state = network.DEVICE_STATE_UNKNOWN - if self._mode != network.NM_802_11_MODE_ADHOC and \ - network.is_sugar_adhoc_network(self._name) == False: + if self._mode == network.NM_802_11_MODE_ADHOC and \ + network.is_sugar_adhoc_network(self._name): + channel = network.frequency_to_channel(self._frequency) + if state == network.DEVICE_STATE_ACTIVATED: + self._icon.props.icon_name = 'network-adhoc-%s-connected' \ + % channel + else: + self._icon.props.icon_name = 'network-adhoc-%s' % channel + self._icon.props.base_color = profile.get_color() + else: if state == network.DEVICE_STATE_ACTIVATED: icon_name = '%s-connected' % 'network-wireless' else: @@ -533,14 +594,6 @@ class WirelessDeviceView(ToolButton): icon_name = get_icon_state(icon_name, self._strength) if icon_name: self._icon.props.icon_name = icon_name - else: - channel = network.frequency_to_channel(self._frequency) - if state == network.DEVICE_STATE_ACTIVATED: - self._icon.props.icon_name = 'network-adhoc-%s-connected' \ - % channel - else: - self._icon.props.icon_name = 'network-adhoc-%s' % channel - self._icon.props.base_color = profile.get_color() if state == network.DEVICE_STATE_PREPARE or \ state == network.DEVICE_STATE_CONFIG or \ @@ -754,6 +807,8 @@ class GsmDeviceView(TrayIcon): def __init__(self, device): self._connection_time_handler = None self._connection_timestamp = 0 + self._shared_connection = None + self._target_dev_path = None client = gconf.client_get_default() color = xocolor.XoColor(client.get_string('/desktop/sugar/user/color')) @@ -780,6 +835,8 @@ class GsmDeviceView(TrayIcon): palette.set_group_id('frame') palette.connect('gsm-connect', self.__gsm_connect_cb) palette.connect('gsm-disconnect', self.__gsm_disconnect_cb) + palette.connect('gsm-neighborhood', self.__gsm_start_sharing_cb) + palette.connect('gsm-private', self.__gsm_stop_sharing_cb) self._palette = palette @@ -904,6 +961,106 @@ class GsmDeviceView(TrayIcon): return True + def __gsm_start_sharing_cb(self, palette): + if self._palette._sharing_state == _GSM_SHARING_PRIVATE: + logging.debug('GSM will start sharing now') + self._palette._sharing_state = _GSM_SHARING_TRYING + self._palette.sharing_update_text() + + nm_obj = self._bus.get_object(_NM_SERVICE, _NM_PATH) + nm_iface = dbus.Interface(nm_obj, _NM_IFACE) + devs_paths = nm_iface.GetDevices() + + target_dev_path = None + for dev_path in devs_paths: + dev_obj = self._bus.get_object(_NM_SERVICE, dev_path) + dev_props = dbus.Interface(dev_obj, _NM_OBJ_PROPERTIES) + device_type = dev_props.Get(_NM_DEVICE_IFACE, 'DeviceType') + if device_type == network.DEVICE_TYPE_802_11_WIRELESS: + target_dev_path = dev_path + break + + if target_dev_path == None: + self._gsm_sharing_reset() + raise RuntimeError('No device for sharing') + self._target_dev_path = target_dev_path + + client = gconf.client_get_default() + nick = client.get_string('/desktop/sugar/user/nick') + nick = re.sub('\W', '', nick) + + name_format = '%s network' + format_length = len(name_format) - len('%s') + nick_length = 31 - format_length + name = name_format % nick[:nick_length] + + connection = network.find_connection_by_ssid(name) + if connection == None: + settings = Settings() + settings.connection.id = name + settings.connection.uuid = unique_id() + settings.connection.type = '802-11-wireless' + settings.wireless.ssid = dbus.ByteArray(name) + settings.wireless.mode = 'adhoc' + settings.wireless.band = 'bg' + chosen_channel = random.randrange(len(_GSM_SHARING_CHANNELS)) + settings.wireless.channel = _GSM_SHARING_CHANNELS[chosen_channel] + settings.ip4_config = IP4Config() + settings.ip4_config.method = 'shared' + connection = network.add_connection(name, settings) + + nm_iface.ActivateConnection(network.SETTINGS_SERVICE, + connection.path, + target_dev_path, + '/', + reply_handler=self.__gsm_sharing_ok_cb, + error_handler=self.__gsm_sharing_error_cb) + + def __gsm_sharing_ok_cb(self, connection): + logging.debug('GSM sharing is enabled') + self._shared_connection = connection + self._bus.add_signal_receiver(self.__gsm_sharing_changed_cb, + signal_name='StateChanged', + path=self._target_dev_path, + dbus_interface=_NM_DEVICE_IFACE) + self._palette._sharing_state = _GSM_SHARING_NEIGHBORHOOD + self._palette.sharing_update_text() + + def __gsm_sharing_changed_cb(self, new_state, old_state, reason): + if new_state == network.DEVICE_STATE_DISCONNECTED: + self._gsm_sharing_reset() + + def _gsm_sharing_reset(self): + logging.debug('GSM sharing is disabled') + if self._target_dev_path != None: + self._bus.remove_signal_receiver(self.__gsm_sharing_changed_cb, + signal_name='StateChanged', + path=self._target_dev_path, + dbus_interface=_NM_DEVICE_IFACE) + self._shared_connection = None + self._target_dev_path = None + self._palette._sharing_state = _GSM_SHARING_PRIVATE + self._palette.sharing_update_text() + + def __gsm_sharing_error_cb(self, error): + logging.debug('GSM sharing could not start: %s' % str(error)) + self._gsm_sharing_reset() + + def __gsm_stop_sharing_cb(self, palette): + logging.debug('GSM will stop sharing now') + nm_obj = self._bus.get_object(_NM_SERVICE, _NM_PATH) + nm_iface = dbus.Interface(nm_obj, _NM_IFACE) + nm_iface.DeactivateConnection( + self._shared_connection, + reply_handler=self.__gsm_stop_sharing_ok_cb, + error_handler=self.__gsm_stop_sharing_error_cb) + + def __gsm_stop_sharing_ok_cb(self): + self._gsm_sharing_reset() + + def __gsm_stop_sharing_error_cb(self): + logging.debug('GSM sharing could not stop') + class WirelessDeviceObserver(object): def __init__(self, device, tray, device_type): |