Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/extensions/deviceicon/network.py
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/deviceicon/network.py')
-rw-r--r--extensions/deviceicon/network.py516
1 files changed, 281 insertions, 235 deletions
diff --git a/extensions/deviceicon/network.py b/extensions/deviceicon/network.py
index 94a4293..4c4f339 100644
--- a/extensions/deviceicon/network.py
+++ b/extensions/deviceicon/network.py
@@ -23,10 +23,10 @@ import logging
import hashlib
import socket
import struct
-import re
import datetime
import time
import gtk
+import glib
import gobject
import gconf
import dbus
@@ -36,17 +36,17 @@ from sugar.graphics import style
from sugar.graphics.palette import Palette
from sugar.graphics.toolbutton import ToolButton
from sugar.graphics.tray import TrayIcon
+from sugar.graphics.menuitem import MenuItem
+from sugar.graphics.icon import Icon
from sugar.graphics import xocolor
-from sugar.util import unique_id
from sugar import profile
from jarabe.model import network
-from jarabe.model.network import Settings
-from jarabe.model.network import IP4Config
from jarabe.frame.frameinvoker import FrameWidgetInvoker
from jarabe.view.pulsingicon import PulsingIcon
-IP_ADDRESS_TEXT_TEMPLATE = _("IP address: %s")
+
+IP_ADDRESS_TEXT_TEMPLATE = _('IP address: %s')
_NM_SERVICE = 'org.freedesktop.NetworkManager'
_NM_IFACE = 'org.freedesktop.NetworkManager'
@@ -63,26 +63,18 @@ _GSM_STATE_NOT_READY = 0
_GSM_STATE_DISCONNECTED = 1
_GSM_STATE_CONNECTING = 2
_GSM_STATE_CONNECTED = 3
-_GSM_STATE_NEED_AUTH = 4
+_GSM_STATE_FAILED = 4
-def frequency_to_channel(frequency):
- 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}
- return ftoc[frequency]
class WirelessPalette(Palette):
__gtype_name__ = 'SugarWirelessPalette'
__gsignals__ = {
- 'deactivate-connection' : (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([])),
- 'create-connection' : (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([])),
+ 'deactivate-connection': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([])),
}
- def __init__(self, primary_text, can_create=True):
+ def __init__(self, primary_text):
Palette.__init__(self, label=primary_text)
self._disconnect_item = None
@@ -109,16 +101,13 @@ class WirelessPalette(Palette):
self._info.pack_start(_padded(self._ip_address_label))
self._info.show_all()
- self._disconnect_item = gtk.MenuItem(_('Disconnect...'))
- self._disconnect_item.connect('activate', self.__disconnect_activate_cb)
+ self._disconnect_item = MenuItem(_('Disconnect...'))
+ icon = Icon(icon_size=gtk.ICON_SIZE_MENU, icon_name='media-eject')
+ self._disconnect_item.set_image(icon)
+ self._disconnect_item.connect('activate',
+ self.__disconnect_activate_cb)
self.menu.append(self._disconnect_item)
- if can_create:
- self._adhoc_item = gtk.MenuItem(_('Create new wireless network'))
- self._adhoc_item.connect('activate', self.__adhoc_activate_cb)
- self.menu.append(self._adhoc_item)
- self._adhoc_item.show()
-
def set_connecting(self):
self.props.secondary_text = _('Connecting...')
@@ -145,18 +134,12 @@ class WirelessPalette(Palette):
def __disconnect_activate_cb(self, menuitem):
self.emit('deactivate-connection')
- def __adhoc_activate_cb(self, menuitem):
- self.emit('create-connection')
-
def _set_frequency(self, frequency):
- try:
- channel = frequency_to_channel(frequency)
- except KeyError:
- channel = 0
+ channel = network.frequency_to_channel(frequency)
self._set_channel(channel)
def _set_channel(self, channel):
- self._channel_label.set_text("%s: %d" % (_("Channel"), channel))
+ self._channel_label.set_text('%s: %d' % (_('Channel'), channel))
def _set_ip_address(self, ip_address):
if ip_address is not None:
@@ -204,7 +187,7 @@ class WiredPalette(Palette):
def _inet_ntoa(self, iaddress):
address = ['%s' % ((iaddress >> i) % 256) for i in [0, 8, 16, 24]]
- return ".".join(address)
+ return '.'.join(address)
def _set_ip_address(self, ip_address):
if ip_address is not None:
@@ -214,14 +197,13 @@ class WiredPalette(Palette):
ip_address_text = ""
self._ip_address_label.set_text(ip_address_text)
+
class GsmPalette(Palette):
__gtype_name__ = 'SugarGsmPalette'
__gsignals__ = {
- 'gsm-connect' : (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([])),
- 'gsm-disconnect' : (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([])),
+ 'gsm-connect': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
+ 'gsm-disconnect': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
}
def __init__(self):
@@ -229,34 +211,53 @@ class GsmPalette(Palette):
Palette.__init__(self, label=_('Wireless modem'))
self._current_state = None
+ self._failed_connection = False
- self._toggle_state_item = gtk.MenuItem('')
+ 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.set_state(_GSM_STATE_NOT_READY)
-
self.info_box = gtk.VBox()
- self.data_label = gtk.Label()
- self.data_label.props.xalign = 0.0
- label_alignment = self._add_widget_with_padding(self.data_label)
- self.info_box.pack_start(label_alignment)
- self.data_label.show()
+ self.error_title_label = gtk.Label("")
+ self.error_title_label.set_alignment(0, 0.5)
+ self.error_title_label.set_line_wrap(True)
+ self.info_box.pack_start(self.error_title_label)
+ self.error_description_label = gtk.Label("")
+ self.error_description_label.set_alignment(0, 0.5)
+ self.error_description_label.set_line_wrap(True)
+ self.info_box.pack_start(self.error_description_label)
+
+ self.connection_info_box = gtk.HBox()
+ icon = Icon(icon_name='data-upload', icon_size=gtk.ICON_SIZE_MENU)
+ self.connection_info_box.pack_start(icon)
+ icon.show()
+
+ self._data_label_up = gtk.Label()
+ self._data_label_up.props.xalign = 0.0
+ label_alignment = self._add_widget_with_padding(self._data_label_up)
+ self.connection_info_box.pack_start(label_alignment)
+ self._data_label_up.show()
label_alignment.show()
- self.connection_time_label = gtk.Label()
- self.connection_time_label.props.xalign = 0.0
- label_alignment = self._add_widget_with_padding( \
- self.connection_time_label)
- self.info_box.pack_start(label_alignment)
- self.connection_time_label.show()
+ icon = Icon(icon_name='data-download', icon_size=gtk.ICON_SIZE_MENU)
+ self.connection_info_box.pack_start(icon)
+ icon.show()
+ self._data_label_down = gtk.Label()
+ self._data_label_down.props.xalign = 0.0
+ label_alignment = self._add_widget_with_padding(self._data_label_down)
+ self.connection_info_box.pack_start(label_alignment)
+ self._data_label_down.show()
label_alignment.show()
+ self.info_box.pack_start(self.connection_info_box)
+
self.info_box.show()
self.set_content(self.info_box)
+ self.set_state(_GSM_STATE_NOT_READY)
+
def _add_widget_with_padding(self, child, xalign=0, yalign=0.5):
alignment = gtk.Alignment(xalign=xalign, yalign=yalign,
xscale=1, yscale=0.33)
@@ -267,31 +268,41 @@ class GsmPalette(Palette):
alignment.add(child)
return alignment
- def set_state(self, state):
+ def update_state(self, state, reason=0):
self._current_state = state
- self._update_label_and_text()
+ self._update_label_and_text(reason)
- def _update_label_and_text(self):
+ def _update_label_and_text(self, reason=0):
if self._current_state == _GSM_STATE_NOT_READY:
self._toggle_state_item.get_child().set_label('...')
self.props.secondary_text = _('Please wait...')
elif self._current_state == _GSM_STATE_DISCONNECTED:
- self._toggle_state_item.get_child().set_label(_('Connect'))
+ if not self._failed_connection:
+ self._toggle_state_item.get_child().set_label(_('Connect'))
self.props.secondary_text = _('Disconnected')
+ icon = Icon(icon_name='dialog-ok', \
+ icon_size=gtk.ICON_SIZE_MENU)
+ self._toggle_state_item.set_image(icon)
elif self._current_state == _GSM_STATE_CONNECTING:
self._toggle_state_item.get_child().set_label(_('Cancel'))
self.props.secondary_text = _('Connecting...')
+ icon = Icon(icon_name='dialog-cancel', \
+ icon_size=gtk.ICON_SIZE_MENU)
+ self._toggle_state_item.set_image(icon)
elif self._current_state == _GSM_STATE_CONNECTED:
+ self._failed_connection = False
self._toggle_state_item.get_child().set_label(_('Disconnect'))
- self.props.secondary_text = _('Connected')
-
- elif self._current_state == _GSM_STATE_NEED_AUTH:
- self._toggle_state_item.get_child().set_label(_('Sim requires Pin/Puk'))
- self.props.secondary_text = _('Authentication Error')
-
+ self.update_connection_time()
+ icon = Icon(icon_name='media-eject', \
+ icon_size=gtk.ICON_SIZE_MENU)
+ self._toggle_state_item.set_image(icon)
+
+ elif self._current_state == _GSM_STATE_FAILED:
+ message_error = self._get_error_by_nm_reason(reason)
+ self.add_alert(message_error[0], message_error[1])
else:
raise ValueError('Invalid GSM state while updating label and ' \
'text, %s' % str(self._current_state))
@@ -300,21 +311,64 @@ class GsmPalette(Palette):
if self._current_state == _GSM_STATE_NOT_READY:
pass
elif self._current_state == _GSM_STATE_DISCONNECTED:
+ self.error_title_label.hide()
+ self.error_description_label.hide()
self.emit('gsm-connect')
elif self._current_state == _GSM_STATE_CONNECTING:
self.emit('gsm-disconnect')
elif self._current_state == _GSM_STATE_CONNECTED:
self.emit('gsm-disconnect')
- elif self._current_state == _GSM_STATE_NEED_AUTH:
- self.emit('gsm-disconnect')
else:
raise ValueError('Invalid GSM state while emitting signal, %s' % \
str(self._current_state))
+ def add_alert(self, error, suggestion):
+ self._failed_connection = True
+ action = _('Try connection again')
+ self._toggle_state_item.get_child().set_label(action)
+
+ title = _('Error: %s') % error
+ self.error_title_label.set_markup('<b>%s</b>' % title)
+ self.error_title_label.show()
+
+ message = _('Suggestion: %s') % suggestion
+ self.error_description_label.set_text(message)
+ self.error_description_label.show()
+
+ def update_connection_time(self, connection_time=None):
+ if connection_time is not None:
+ self.props.secondary_text = _('Connected for %s') % \
+ connection_time.strftime('%H:%M:%S')
+ else:
+ self.props.secondary_text = _('Connected for %s') % '00:00:00'
+
+ def update_stats(self, in_bytes, out_bytes):
+ in_KBytes = in_bytes / 1024
+ out_KBytes = out_bytes / 1024
+ self._data_label_up.set_text(_('%d KB') % (out_KBytes))
+ self._data_label_down.set_text(_('%d KB') % (in_KBytes))
+
+ def _get_error_by_nm_reason(self, reason):
+ if reason in [network.NM_DEVICE_STATE_REASON_NO_SECRETS,
+ network.NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED]:
+ message = _('Check your Pin/Puk configuration.')
+ elif reason in [network.NM_DEVICE_STATE_REASON_PPP_DISCONNECT,
+ network.NM_DEVICE_STATE_REASON_PPP_FAILED]:
+ message = _('Check your Access Point Name ' \
+ '(APN) configuration')
+ elif reason in [network.NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER,
+ network.NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT]:
+ message = _('Check the Number configuration.')
+ elif reason == network.NM_DEVICE_STATE_REASON_CONFIG_FAILED:
+ message = _('Check your configuration.')
+ else:
+ message = ''
+ message_tuple = (network.get_error_by_reason(reason), message)
+ return message_tuple
+
class WirelessDeviceView(ToolButton):
- _ICON_NAME = 'network-wireless'
FRAME_POSITION_RELATIVE = 302
def __init__(self, device):
@@ -333,9 +387,9 @@ class WirelessDeviceView(ToolButton):
self._active_ap_op = None
self._icon = PulsingIcon()
- self._icon.props.icon_name = get_icon_state(self._ICON_NAME, 0)
- self._inactive_color = xocolor.XoColor( \
- "%s,%s" % (style.COLOR_BUTTON_GREY.get_svg(),
+ self._icon.props.icon_name = get_icon_state('network-wireless', 0)
+ self._inactive_color = xocolor.XoColor(
+ '%s,%s' % (style.COLOR_BUTTON_GREY.get_svg(),
style.COLOR_TRANSPARENT.get_svg()))
self._icon.props.pulse_color = self._inactive_color
self._icon.props.base_color = self._inactive_color
@@ -347,14 +401,12 @@ class WirelessDeviceView(ToolButton):
self._palette = WirelessPalette(self._name)
self._palette.connect('deactivate-connection',
self.__deactivate_connection_cb)
- self._palette.connect('create-connection',
- self.__create_connection_cb)
self.set_palette(self._palette)
self._palette.set_group_id('frame')
- self._device_props = dbus.Interface(self._device,
- 'org.freedesktop.DBus.Properties')
- self._device_props.GetAll(_NM_DEVICE_IFACE, byte_arrays=True,
+ self._device_props = dbus.Interface(self._device,
+ dbus.PROPERTIES_IFACE)
+ self._device_props.GetAll(_NM_DEVICE_IFACE, byte_arrays=True,
reply_handler=self.__get_device_props_reply_cb,
error_handler=self.__get_device_props_error_cb)
@@ -394,7 +446,7 @@ class WirelessDeviceView(ToolButton):
return
self._active_ap_op = active_ap_op
active_ap = self._bus.get_object(_NM_SERVICE, active_ap_op)
- props = dbus.Interface(active_ap, 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(active_ap, dbus.PROPERTIES_IFACE)
props.GetAll(_NM_ACCESSPOINT_IFACE, byte_arrays=True,
reply_handler=self.__get_all_ap_props_reply_cb,
@@ -418,11 +470,6 @@ class WirelessDeviceView(ToolButton):
def __ap_properties_changed_cb(self, properties):
self._update_properties(properties)
- def _name_encodes_colors(self):
- """Match #XXXXXX,#YYYYYY at the end of the network name"""
- return self._name[-7] == '#' and self._name[-8] == ',' \
- and self._name[-15] == '#'
-
def _update_properties(self, properties):
if 'Mode' in properties:
self._mode = properties['Mode']
@@ -438,11 +485,9 @@ class WirelessDeviceView(ToolButton):
self._frequency = properties['Frequency']
if self._color == None:
- if self._mode == network.NM_802_11_MODE_ADHOC \
- and self._name_encodes_colors():
- encoded_color = self._name.split("#", 1)
- if len(encoded_color) == 2:
- self._color = xocolor.XoColor('#' + encoded_color[1])
+ if self._mode == network.NM_802_11_MODE_ADHOC and \
+ network.is_sugar_adhoc_network(self._name):
+ self._color = profile.get_color()
else:
sha_hash = hashlib.sha1()
data = self._name + hex(self._flags)
@@ -450,7 +495,7 @@ class WirelessDeviceView(ToolButton):
digest = hash(sha_hash.digest())
index = digest % len(xocolor.colors)
- self._color = xocolor.XoColor('%s,%s' %
+ self._color = xocolor.XoColor('%s,%s' %
(xocolor.colors[index][0],
xocolor.colors[index][1]))
self._update()
@@ -463,11 +508,11 @@ class WirelessDeviceView(ToolButton):
def _update(self):
if self._flags == network.NM_802_11_AP_FLAGS_PRIVACY:
- self._icon.props.badge_name = "emblem-locked"
+ self._icon.props.badge_name = 'emblem-locked'
else:
self._icon.props.badge_name = None
- self._palette.props.primary_text = self._name
+ self._palette.props.primary_text = glib.markup_escape_text(self._name)
self._update_state()
self._update_color()
@@ -478,14 +523,24 @@ class WirelessDeviceView(ToolButton):
else:
state = network.DEVICE_STATE_UNKNOWN
- if state == network.DEVICE_STATE_ACTIVATED:
- icon_name = '%s-connected' % self._ICON_NAME
- else:
- icon_name = self._ICON_NAME
+ if self._mode != network.NM_802_11_MODE_ADHOC and \
+ network.is_sugar_adhoc_network(self._name) == False:
+ if state == network.DEVICE_STATE_ACTIVATED:
+ icon_name = '%s-connected' % 'network-wireless'
+ else:
+ icon_name = 'network-wireless'
- icon_name = get_icon_state(icon_name, self._strength)
- if icon_name:
- self._icon.props.icon_name = icon_name
+ 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 \
@@ -495,7 +550,8 @@ class WirelessDeviceView(ToolButton):
self._icon.props.pulsing = True
elif state == network.DEVICE_STATE_ACTIVATED:
address = self._device_props.Get(_NM_DEVICE_IFACE, 'Ip4Address')
- self._palette.set_connected_with_frequency(self._frequency, address)
+ self._palette.set_connected_with_frequency(self._frequency,
+ address)
self._icon.props.pulsing = False
else:
self._icon.props.badge_name = None
@@ -508,69 +564,12 @@ class WirelessDeviceView(ToolButton):
self._icon.props.base_color = self._color
def __deactivate_connection_cb(self, palette, data=None):
- if self._active_ap_op is not None:
- obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
- netmgr = dbus.Interface(obj, _NM_IFACE)
- netmgr_props = dbus.Interface(
- netmgr, 'org.freedesktop.DBus.Properties')
- active_connections_o = netmgr_props.Get(_NM_IFACE,
- 'ActiveConnections')
-
- for conn_o in active_connections_o:
- obj = self._bus.get_object(_NM_IFACE, conn_o)
- props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
- ap_op = props.Get(_NM_ACTIVE_CONN_IFACE, 'SpecificObject')
- if ap_op == self._active_ap_op:
- netmgr.DeactivateConnection(conn_o)
- break
-
- def __create_connection_cb(self, palette, data=None):
- """Create an 802.11 IBSS network.
-
- The user's color is encoded at the end of the network name. The network
- name is truncated so that it does not exceed the 32 byte SSID limit.
- """
- client = gconf.client_get_default()
- nick = client.get_string('/desktop/sugar/user/nick').decode('utf-8')
- color = client.get_string('/desktop/sugar/user/color')
- color_suffix = ' %s' % color
-
- format = _('%s\'s network').encode('utf-8')
- extra_length = (len(format) - len('%s')) + len(color_suffix)
- name_limit = 32 - extra_length
-
- # truncate the nick and use a regex to drop any partial characters
- # at the end
- nick = nick.encode('utf-8')[:name_limit]
- pattern = "([\xf6-\xf7][\x80-\xbf]{0,2}|[\xe0-\xef][\x80-\xbf]{0,1}|[\xc0-\xdf])$"
- nick = re.sub(pattern, '', nick)
-
- connection_name = format % nick
- connection_name += color_suffix
-
- connection = network.find_connection_by_ssid(connection_name)
- if connection is None:
- settings = Settings()
- settings.connection.id = 'Auto ' + connection_name
- uuid = settings.connection.uuid = unique_id()
- settings.connection.type = '802-11-wireless'
- settings.wireless.ssid = dbus.ByteArray(connection_name)
- settings.wireless.band = 'bg'
- settings.wireless.mode = 'adhoc'
- settings.ip4_config = IP4Config()
- settings.ip4_config.method = 'link-local'
-
- connection = network.add_connection(uuid, settings)
+ if self._mode == network.NM_802_11_MODE_INFRA:
+ connection = network.find_connection_by_ssid(self._name)
+ if connection:
+ connection.disable_autoconnect()
- obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
- netmgr = dbus.Interface(obj, _NM_IFACE)
-
- netmgr.ActivateConnection(network.SETTINGS_SERVICE,
- connection.path,
- self._device.object_path,
- '/',
- reply_handler=self.__activate_reply_cb,
- error_handler=self.__activate_error_cb)
+ network.disconnect_access_points([self._active_ap_op])
def __activate_reply_cb(self, connection):
logging.debug('Network created: %s', connection)
@@ -583,7 +582,7 @@ class OlpcMeshDeviceView(ToolButton):
_ICON_NAME = 'network-mesh'
FRAME_POSITION_RELATIVE = 302
- def __init__(self, device):
+ def __init__(self, device, state):
ToolButton.__init__(self)
self._bus = dbus.SystemBus()
@@ -593,57 +592,41 @@ class OlpcMeshDeviceView(ToolButton):
self._channel = 0
self._icon = PulsingIcon(icon_name=self._ICON_NAME)
- self._icon.props.pulse_color = xocolor.XoColor( \
- "%s,%s" % (style.COLOR_BUTTON_GREY.get_svg(),
+ self._inactive_color = xocolor.XoColor(
+ '%s,%s' % (style.COLOR_BUTTON_GREY.get_svg(),
style.COLOR_TRANSPARENT.get_svg()))
- self._icon.props.base_color = profile.get_color()
+ self._icon.props.pulse_color = profile.get_color()
+ self._icon.props.base_color = self._inactive_color
self.set_icon_widget(self._icon)
self._icon.show()
self.set_palette_invoker(FrameWidgetInvoker(self))
- self._palette = WirelessPalette(_("Mesh Network"))
+ self._palette = WirelessPalette(_('Mesh Network'))
self._palette.connect('deactivate-connection',
self.__deactivate_connection)
self.set_palette(self._palette)
self._palette.set_group_id('frame')
+ self.update_state(state)
+
self._device_props = dbus.Interface(self._device,
- 'org.freedesktop.DBus.Properties')
- self._device_props.GetAll(_NM_DEVICE_IFACE, byte_arrays=True,
- reply_handler=self.__get_device_props_reply_cb,
- error_handler=self.__get_device_props_error_cb)
+ dbus.PROPERTIES_IFACE)
self._device_props.Get(_NM_OLPC_MESH_IFACE, 'ActiveChannel',
reply_handler=self.__get_active_channel_reply_cb,
error_handler=self.__get_active_channel_error_cb)
- self._bus.add_signal_receiver(self.__state_changed_cb,
- signal_name='StateChanged',
- path=self._device.object_path,
- dbus_interface=_NM_DEVICE_IFACE)
self._bus.add_signal_receiver(self.__wireless_properties_changed_cb,
signal_name='PropertiesChanged',
path=device.object_path,
dbus_interface=_NM_OLPC_MESH_IFACE)
def disconnect(self):
- self._bus.remove_signal_receiver(self.__state_changed_cb,
- signal_name='StateChanged',
- path=self._device.object_path,
- dbus_interface=_NM_DEVICE_IFACE)
self._bus.remove_signal_receiver(self.__wireless_properties_changed_cb,
signal_name='PropertiesChanged',
path=self._device.object_path,
dbus_interface=_NM_OLPC_MESH_IFACE)
- def __get_device_props_reply_cb(self, properties):
- if 'State' in properties:
- self._device_state = properties['State']
- self._update()
-
- def __get_device_props_error_cb(self, err):
- logging.error('Error getting the device properties: %s', err)
-
def __get_active_channel_reply_cb(self, channel):
self._channel = channel
self._update_text()
@@ -661,7 +644,8 @@ class OlpcMeshDeviceView(ToolButton):
self._update_text()
def _update_text(self):
- text = _("Mesh Network") + " " + str(self._channel)
+ channel = str(self._channel)
+ text = _('Mesh Network %s') % glib.markup_escape_text(channel)
self._palette.props.primary_text = text
def _update(self):
@@ -671,31 +655,39 @@ class OlpcMeshDeviceView(ToolButton):
network.DEVICE_STATE_CONFIG,
network.DEVICE_STATE_NEED_AUTH,
network.DEVICE_STATE_IP_CONFIG]:
+ self._icon.props.base_color = self._inactive_color
+ self._icon.props.pulse_color = profile.get_color()
self._palette.set_connecting()
self._icon.props.pulsing = True
elif state == network.DEVICE_STATE_ACTIVATED:
address = self._device_props.Get(_NM_DEVICE_IFACE, 'Ip4Address')
self._palette.set_connected_with_channel(self._channel, address)
+ self._icon.props.base_color = profile.get_color()
self._icon.props.pulsing = False
+ self._update_text()
+
+ def update_state(self, state):
+ self._device_state = state
+ self._update()
def __deactivate_connection(self, palette, data=None):
obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
netmgr = dbus.Interface(obj, _NM_IFACE)
- netmgr_props = dbus.Interface(netmgr, 'org.freedesktop.DBus.Properties')
+ netmgr_props = dbus.Interface(netmgr, dbus.PROPERTIES_IFACE)
active_connections_o = netmgr_props.Get(_NM_IFACE,
'ActiveConnections')
for conn_o in active_connections_o:
# The connection path for a mesh connection is the device itself.
obj = self._bus.get_object(_NM_IFACE, conn_o)
- props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
ap_op = props.Get(_NM_ACTIVE_CONN_IFACE, 'SpecificObject')
try:
obj = self._bus.get_object(_NM_IFACE, ap_op)
- props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
- type = props.Get(_NM_DEVICE_IFACE, 'DeviceType')
- if type == network.DEVICE_TYPE_802_11_OLPC_MESH:
+ props = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
+ device_type = props.Get(_NM_DEVICE_IFACE, 'DeviceType')
+ if device_type == network.DEVICE_TYPE_802_11_OLPC_MESH:
netmgr.DeactivateConnection(conn_o)
break
except dbus.exceptions.DBusException:
@@ -747,6 +739,7 @@ class GsmDeviceView(TrayIcon):
signal_name='PppStats',
path=self._device.object_path,
dbus_interface=_NM_SERIAL_IFACE)
+
def create_palette(self):
palette = GsmPalette()
@@ -756,7 +749,7 @@ class GsmDeviceView(TrayIcon):
self._palette = palette
- props = dbus.Interface(self._device, 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(self._device, dbus.PROPERTIES_IFACE)
props.GetAll(_NM_DEVICE_IFACE, byte_arrays=True,
reply_handler=self.__current_state_check_cb,
error_handler=self.__current_state_check_error_cb)
@@ -774,6 +767,10 @@ class GsmDeviceView(TrayIcon):
'/',
reply_handler=self.__connect_cb,
error_handler=self.__connect_error_cb)
+ else:
+ self._palette.add_alert(_('No GSM connection available.'), \
+ _('Create a connection in the ' \
+ 'control panel.'))
def __connect_cb(self, active_connection):
logging.debug('Connected successfully to gsm device, %s',
@@ -785,12 +782,12 @@ class GsmDeviceView(TrayIcon):
def __gsm_disconnect_cb(self, palette, data=None):
obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
netmgr = dbus.Interface(obj, _NM_IFACE)
- netmgr_props = dbus.Interface(netmgr, 'org.freedesktop.DBus.Properties')
+ netmgr_props = dbus.Interface(netmgr, dbus.PROPERTIES_IFACE)
active_connections_o = netmgr_props.Get(_NM_IFACE, 'ActiveConnections')
for conn_o in active_connections_o:
obj = self._bus.get_object(_NM_IFACE, conn_o)
- props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
devices = props.Get(_NM_ACTIVE_CONN_IFACE, 'Devices')
if self._device.object_path in devices:
netmgr.DeactivateConnection(
@@ -806,16 +803,17 @@ class GsmDeviceView(TrayIcon):
raise RuntimeError('Error when disconnecting gsm device, %s' % error)
def __state_changed_cb(self, new_state, old_state, reason):
- logging.debug('State: %s to %s, reason %s', old_state, new_state, reason)
- self._update_state(int(new_state))
+ logging.debug('State: %s to %s, reason %s', old_state,
+ new_state, reason)
+ self._update_state(int(new_state), int(old_state), int(reason))
def __current_state_check_cb(self, properties):
- self._update_state(int(properties['State']))
+ self._update_state(int(properties['State']), 0, 0)
def __current_state_check_error_cb(self, error):
raise RuntimeError('Error when checking gsm device state, %s' % error)
- def _update_state(self, state):
+ def _update_state(self, state, old_state, reason):
gsm_state = None
if state is network.DEVICE_STATE_ACTIVATED:
@@ -823,20 +821,22 @@ class GsmDeviceView(TrayIcon):
connection = network.find_gsm_connection()
if connection is not None:
connection.set_connected()
- self._connection_timestamp = time.time() - \
+ self._connection_timestamp = time.time() - \
connection.get_settings().connection.timestamp
self._connection_time_handler = gobject.timeout_add_seconds( \
1, self.__connection_timecount_cb)
- self._update_stats(0, 0)
- self._update_connection_time()
- self._palette.info_box.show()
+ self._palette.update_connection_time()
+ self._palette.update_stats(0, 0)
+ if self._palette is not None:
+ self._palette.connection_info_box.show()
elif state is network.DEVICE_STATE_DISCONNECTED:
gsm_state = _GSM_STATE_DISCONNECTED
self._connection_timestamp = 0
if self._connection_time_handler is not None:
gobject.source_remove(self._connection_time_handler)
- self._palette.info_box.hide()
+ if self._palette is not None:
+ self._palette.connection_info_box.hide()
elif state in [network.DEVICE_STATE_UNMANAGED,
network.DEVICE_STATE_UNAVAILABLE,
@@ -845,14 +845,15 @@ class GsmDeviceView(TrayIcon):
elif state in [network.DEVICE_STATE_PREPARE,
network.DEVICE_STATE_CONFIG,
- network.DEVICE_STATE_IP_CONFIG]:
+ network.DEVICE_STATE_IP_CONFIG,
+ network.DEVICE_STATE_NEED_AUTH]:
gsm_state = _GSM_STATE_CONNECTING
-
- elif state in [network.DEVICE_STATE_NEED_AUTH]:
- gsm_state = _GSM_STATE_NEED_AUTH
-
+
+ elif state == network.DEVICE_STATE_FAILED:
+ gsm_state = _GSM_STATE_FAILED
+
if self._palette is not None:
- self._palette.set_state(gsm_state)
+ self._palette.update_state(gsm_state, reason)
def disconnect(self):
self._bus.remove_signal_receiver(self.__state_changed_cb,
@@ -861,38 +862,22 @@ class GsmDeviceView(TrayIcon):
dbus_interface=_NM_DEVICE_IFACE)
def __ppp_stats_changed_cb(self, in_bytes, out_bytes):
- self._update_stats(in_bytes, out_bytes)
-
- def _update_stats(self, in_bytes, out_bytes):
- in_KBytes = in_bytes / 1024
- out_KBytes = out_bytes / 1024
- text = _("Data sent %d KB / received %d KB") % (out_KBytes, in_KBytes)
- self._palette.data_label.set_text(text)
+ self._palette.update_stats(in_bytes, out_bytes)
def __connection_timecount_cb(self):
self._connection_timestamp = self._connection_timestamp + 1
- self._update_connection_time()
+ connection_time = \
+ datetime.datetime.fromtimestamp(self._connection_timestamp)
+ self._palette.update_connection_time(connection_time)
return True
- def _update_connection_time(self):
- connection_time = datetime.datetime.fromtimestamp( \
- self._connection_timestamp)
- text = _("Connection time ") + connection_time.strftime('%H : %M : %S')
- self._palette.connection_time_label.set_text(text)
class WirelessDeviceObserver(object):
- def __init__(self, device, tray, device_type):
+ def __init__(self, device, tray):
self._device = device
self._device_view = None
self._tray = tray
-
- if device_type == network.DEVICE_TYPE_802_11_WIRELESS:
- self._device_view = WirelessDeviceView(self._device)
- elif device_type == network.DEVICE_TYPE_802_11_OLPC_MESH:
- self._device_view = OlpcMeshDeviceView(self._device)
- else:
- raise ValueError('Unimplemented device type %d' % device_type)
-
+ self._device_view = WirelessDeviceView(self._device)
self._tray.add_device(self._device_view)
def disconnect(self):
@@ -902,6 +887,63 @@ class WirelessDeviceObserver(object):
self._device_view = None
+class MeshDeviceObserver(object):
+ def __init__(self, device, tray):
+ self._bus = dbus.SystemBus()
+ self._device = device
+ self._device_view = None
+ self._tray = tray
+
+ props = dbus.Interface(self._device, dbus.PROPERTIES_IFACE)
+ props.GetAll(_NM_DEVICE_IFACE, byte_arrays=True,
+ reply_handler=self.__get_device_props_reply_cb,
+ error_handler=self.__get_device_props_error_cb)
+
+ self._bus.add_signal_receiver(self.__state_changed_cb,
+ signal_name='StateChanged',
+ path=self._device.object_path,
+ dbus_interface=_NM_DEVICE_IFACE)
+
+ def _remove_device_view(self):
+ self._device_view.disconnect()
+ self._tray.remove_device(self._device_view)
+ self._device_view = None
+
+ def disconnect(self):
+ if self._device_view is not None:
+ self._remove_device_view()
+
+ self._bus.remove_signal_receiver(self.__state_changed_cb,
+ signal_name='StateChanged',
+ path=self._device.object_path,
+ dbus_interface=_NM_DEVICE_IFACE)
+
+ def __get_device_props_reply_cb(self, properties):
+ if 'State' in properties:
+ self._update_state(properties['State'])
+
+ def __get_device_props_error_cb(self, err):
+ logging.error('Error getting the device properties: %s', err)
+
+ def __state_changed_cb(self, new_state, old_state, reason):
+ self._update_state(new_state)
+
+ def _update_state(self, state):
+ if state in (network.DEVICE_STATE_PREPARE, network.DEVICE_STATE_CONFIG,
+ network.DEVICE_STATE_NEED_AUTH,
+ network.DEVICE_STATE_IP_CONFIG,
+ network.DEVICE_STATE_ACTIVATED):
+ if self._device_view is not None:
+ self._device_view.update_state(state)
+ return
+
+ self._device_view = OlpcMeshDeviceView(self._device, state)
+ self._tray.add_device(self._device_view)
+ else:
+ if self._device_view is not None:
+ self._remove_device_view()
+
+
class WiredDeviceObserver(object):
def __init__(self, device, tray):
self._bus = dbus.SystemBus()
@@ -910,7 +952,7 @@ class WiredDeviceObserver(object):
self._device_view = None
self._tray = tray
- props = dbus.Interface(self._device, 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(self._device, dbus.PROPERTIES_IFACE)
props.GetAll(_NM_DEVICE_IFACE, byte_arrays=True,
reply_handler=self.__get_device_props_reply_cb,
error_handler=self.__get_device_props_error_cb)
@@ -938,8 +980,7 @@ class WiredDeviceObserver(object):
def _update_state(self, state):
if state == network.DEVICE_STATE_ACTIVATED:
- props = dbus.Interface(self._device,
- 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(self._device, dbus.PROPERTIES_IFACE)
address = props.Get(_NM_DEVICE_IFACE, 'Ip4Address')
speed = props.Get(_NM_WIRED_IFACE, 'Speed')
self._device_view = WiredDeviceView(speed, address)
@@ -950,6 +991,7 @@ class WiredDeviceObserver(object):
del self._device_view
self._device_view = None
+
class GsmDeviceObserver(object):
def __init__(self, device, tray):
self._device = device
@@ -964,6 +1006,7 @@ class GsmDeviceObserver(object):
self._tray.remove_device(self._device_view)
self._device_view = None
+
class NetworkManagerObserver(object):
def __init__(self, tray):
self._bus = dbus.SystemBus()
@@ -997,15 +1040,17 @@ class NetworkManagerObserver(object):
def _check_device(self, device_op):
nm_device = self._bus.get_object(_NM_SERVICE, device_op)
- props = dbus.Interface(nm_device, 'org.freedesktop.DBus.Properties')
+ props = dbus.Interface(nm_device, dbus.PROPERTIES_IFACE)
device_type = props.Get(_NM_DEVICE_IFACE, 'DeviceType')
if device_type == network.DEVICE_TYPE_802_3_ETHERNET:
device = WiredDeviceObserver(nm_device, self._tray)
self._devices[device_op] = device
- elif device_type in [network.DEVICE_TYPE_802_11_WIRELESS,
- network.DEVICE_TYPE_802_11_OLPC_MESH]:
- device = WirelessDeviceObserver(nm_device, self._tray, device_type)
+ elif device_type == network.DEVICE_TYPE_802_11_WIRELESS:
+ device = WirelessDeviceObserver(nm_device, self._tray)
+ self._devices[device_op] = device
+ elif device_type == network.DEVICE_TYPE_802_11_OLPC_MESH:
+ device = MeshDeviceObserver(nm_device, self._tray)
self._devices[device_op] = device
elif device_type == network.DEVICE_TYPE_GSM_MODEM:
device = GsmDeviceObserver(nm_device, self._tray)
@@ -1020,5 +1065,6 @@ class NetworkManagerObserver(object):
device.disconnect()
del self._devices[device_op]
+
def setup(tray):
device_observer = NetworkManagerObserver(tray)