Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin 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)
commit2b37c6a1b060c58cedd143bc17cfd66f5962c90c (patch)
tree196daf2aa9d2ba094e70a648d88ee74b185a220c
parent259c6f294cf3a22c6644b965fb9ec32ccb92db04 (diff)
Share 3g connection
dextrose backport Signed-off-by: Anish Mangal <anish@sugarlabs.org>
-rw-r--r--extensions/deviceicon/network.py177
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):