[Sugar-devel] 3G Support: show connection errors- Patch 1759
Daniel Castelo
dcastelo at plan.ceibal.edu.uy
Tue May 18 15:26:44 EDT 2010
I have this ticket pending, could you give your feedback? Thanks!!!
http://bugs.sugarlabs.org/ticket/1759
This patch improves the feature 3G Support (added in 0.88).
Includes:
Show the connection errors
Apply Eben's Mockup:
http://wiki.sugarlabs.org/go/File:3G_device.png<http://wiki.sugarlabs.org/go/File:3G_device.png>
---
extensions/deviceicon/network.py | 183
++++++++++++++++++++++++++------------
src/jarabe/model/network.py | 34 +++++---
2 files changed, 148 insertions(+), 69 deletions(-)
diff --git a/extensions/deviceicon/network.py
b/extensions/deviceicon/network.py
index 94a4293..995446c 100644
--- a/extensions/deviceicon/network.py
+++ b/extensions/deviceicon/network.py
@@ -39,6 +39,8 @@ from sugar.graphics.tray import TrayIcon
from sugar.graphics import xocolor
from sugar.util import unique_id
from sugar import profile
+from sugar.graphics.icon import Icon
+from sugar.graphics.menuitem import MenuItem
from jarabe.model import network
from jarabe.model.network import Settings
@@ -63,7 +65,7 @@ _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,
@@ -214,6 +216,7 @@ class WiredPalette(Palette):
ip_address_text = ""
self._ip_address_label.set_text(ip_address_text)
+
class GsmPalette(Palette):
__gtype_name__ = 'SugarGsmPalette'
@@ -227,36 +230,48 @@ class GsmPalette(Palette):
def __init__(self):
Palette.__init__(self, label=_('Wireless modem'))
-
self._current_state = None
+ self._alert = 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.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._error_accept_item = MenuItem('')
+ self._error_accept_item.connect('activate', self.__error_accept_cb)
+ self.menu.append(self._error_accept_item)
+
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,35 +282,89 @@ class GsmPalette(Palette):
alignment.add(child)
return alignment
- def set_state(self, state):
+ def set_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'))
- self.props.secondary_text = _('Disconnected')
-
+ if not self._alert:
+ 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._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:
+ self.add_alert(_('Connection Error'), \
+ self._get_error_by_nm_reason(reason))
else:
raise ValueError('Invalid GSM state while updating label and '
\
'text, %s' % str(self._current_state))
-
+
+ def add_alert(self, title, message):
+ self._alert = True
+ self.props.secondary_text = title
+ self._error_accept_item.get_child().set_label(message)
+ self._error_accept_item.show()
+ self._toggle_state_item.set_sensitive(False)
+
+
+ def __error_accept_cb(self, alert):
+ self._alert = False
+ self._update_label_and_text()
+ self._error_accept_item.get_child().set_label('')
+ self._error_accept_item.hide()
+ self._toggle_state_item.set_sensitive(True)
+ self._full_request = [0, 0]
+
+ def update_connection_time(self, connection_time=None):
+ if (connection_time is not None):
+ self.props.secondary_text = _('Connected for ' + \
+ connection_time.strftime('%H:%M:%S'))
+ else:
+ self.props.secondary_text = _('Connected for ' \
+ + '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 = _('The Pin/Puk configuration is not valid.')
+ elif reason in [network.NM_DEVICE_STATE_REASON_PPP_DISCONNECT,
network.NM_DEVICE_STATE_REASON_PPP_FAILED]:
+ message = _('Check the APN configuration.')
+ elif reason in [network.NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER]:
+ message = _('Check the tel number configuration.')
+ elif reason in [network.NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT]:
+ message = _('Time out. Check the tel configuration')
+ else:
+ message = _('Unexpected error.')
+ return message
+
def __toggle_state_cb(self, menuitem):
if self._current_state == _GSM_STATE_NOT_READY:
pass
@@ -305,12 +374,10 @@ class GsmPalette(Palette):
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))
-
+
class WirelessDeviceView(ToolButton):
@@ -747,6 +814,7 @@ class GsmDeviceView(TrayIcon):
signal_name='PppStats',
path=self._device.object_path,
dbus_interface=_NM_SERIAL_IFACE)
+
def create_palette(self):
palette = GsmPalette()
@@ -774,6 +842,9 @@ class GsmDeviceView(TrayIcon):
'/',
reply_handler=self.__connect_cb,
error_handler=self.__connect_error_cb)
+ else:
+ self._palette.add_alert(_('Connection Error'), \
+ _('There is no gsm connection
available'))
def __connect_cb(self, active_connection):
logging.debug('Connected successfully to gsm device, %s',
@@ -807,15 +878,15 @@ class GsmDeviceView(TrayIcon):
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))
+ 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 +894,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 +918,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.set_state(gsm_state, reason)
def disconnect(self):
self._bus.remove_signal_receiver(self.__state_changed_cb,
@@ -861,25 +935,17 @@ 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):
self._device = device
@@ -950,6 +1016,7 @@ class WiredDeviceObserver(object):
del self._device_view
self._device_view = None
+
class GsmDeviceObserver(object):
def __init__(self, device, tray):
self._device = device
diff --git a/src/jarabe/model/network.py b/src/jarabe/model/network.py
index 3a949da..579ed8d 100644
--- a/src/jarabe/model/network.py
+++ b/src/jarabe/model/network.py
@@ -54,6 +54,13 @@ NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0
NM_ACTIVE_CONNECTION_STATE_ACTIVATING = 1
NM_ACTIVE_CONNECTION_STATE_ACTIVATED = 2
+NM_DEVICE_STATE_REASON_NO_SECRETS = 7
+NM_DEVICE_STATE_REASON_PPP_DISCONNECT = 13
+NM_DEVICE_STATE_REASON_PPP_FAILED = 14
+NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER = 25
+NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT = 26
+NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED = 34
+
NM_802_11_AP_FLAGS_NONE = 0x00000000
NM_802_11_AP_FLAGS_PRIVACY = 0x00000001
@@ -444,17 +451,22 @@ class NMSettingsConnection(dbus.service.Object):
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')
- else:
- reply(self._secrets.get_dict())
-
-
+ if self._settings.connection.type is not '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:
+ 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,
--
1.6.2.5
--
Ing. Daniel Castelo
Plan Ceibal - Área Técnica
Avda. Italia 6201
Montevideo - Uruguay.
Tel.: 601.57.73 Interno 2228
E-mail : dcastelo at plan.ceibal.edu.uy
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.sugarlabs.org/archive/sugar-devel/attachments/20100518/34dd442c/attachment-0001.htm
More information about the Sugar-devel
mailing list