Ticket #1759: 0001-3G-Support-show-connection-errors-1759.patch

File 0001-3G-Support-show-connection-errors-1759.patch, 23.3 KB (added by erikos, 14 years ago)

New patch that does address Tomeu's comments and a slightly modified design (after discussion with Gary)

  • extensions/deviceicon/network.py

    From 51dd18881f0f3563a2ab860cae28ba41ca576100 Mon Sep 17 00:00:00 2001
    From: Simon Schampijer <simon@schampijer.de>
    Date: Tue, 24 Aug 2010 11:17:30 +0200
    Subject: [PATCH] 3G Support: show connection errors #1759
    
    ---
     extensions/deviceicon/network.py |  179 ++++++++++++++++++++++++++------------
     src/jarabe/model/network.py      |  166 +++++++++++++++++++++++++++++++++--
     2 files changed, 281 insertions(+), 64 deletions(-)
    
    diff --git a/extensions/deviceicon/network.py b/extensions/deviceicon/network.py
    index 6171f39..0789f9c 100644
    a b _GSM_STATE_NOT_READY = 0 
    6666_GSM_STATE_DISCONNECTED = 1
    6767_GSM_STATE_CONNECTING = 2
    6868_GSM_STATE_CONNECTED = 3
    69 _GSM_STATE_NEED_AUTH = 4
     69_GSM_STATE_FAILED = 4
    7070
    7171
    7272class WirelessPalette(Palette):
    class GsmPalette(Palette): 
    214214        Palette.__init__(self, label=_('Wireless modem'))
    215215
    216216        self._current_state = None
     217        self._failed_connection = False
    217218
    218         self._toggle_state_item = gtk.MenuItem('')
     219        self._toggle_state_item = MenuItem('')
    219220        self._toggle_state_item.connect('activate', self.__toggle_state_cb)
    220221        self.menu.append(self._toggle_state_item)
    221222        self._toggle_state_item.show()
    222223
    223         self.set_state(_GSM_STATE_NOT_READY)
    224 
    225224        self.info_box = gtk.VBox()
    226225
    227         self.data_label = gtk.Label()
    228         self.data_label.props.xalign = 0.0
    229         label_alignment = self._add_widget_with_padding(self.data_label)
    230         self.info_box.pack_start(label_alignment)
    231         self.data_label.show()
     226        self.error_title_label = gtk.Label("")
     227        self.error_title_label.set_alignment(0, 0.5)
     228        self.error_title_label.set_line_wrap(True)
     229        self.info_box.pack_start(self.error_title_label)
     230        self.error_description_label = gtk.Label("")
     231        self.error_description_label.set_alignment(0, 0.5)
     232        self.error_description_label.set_line_wrap(True)
     233        self.info_box.pack_start(self.error_description_label)
     234
     235        self.connection_info_box = gtk.HBox()
     236        icon = Icon(icon_name='data-upload', icon_size=gtk.ICON_SIZE_MENU)
     237        self.connection_info_box.pack_start(icon)
     238        icon.show()
     239
     240        self._data_label_up = gtk.Label()
     241        self._data_label_up.props.xalign = 0.0
     242        label_alignment = self._add_widget_with_padding(self._data_label_up)
     243        self.connection_info_box.pack_start(label_alignment)
     244        self._data_label_up.show()
    232245        label_alignment.show()
    233246
    234         self.connection_time_label = gtk.Label()
    235         self.connection_time_label.props.xalign = 0.0
    236         label_alignment = self._add_widget_with_padding( \
    237                 self.connection_time_label)
    238         self.info_box.pack_start(label_alignment)
    239         self.connection_time_label.show()
     247        icon = Icon(icon_name='data-download', icon_size=gtk.ICON_SIZE_MENU)
     248        self.connection_info_box.pack_start(icon)
     249        icon.show()
     250        self._data_label_down = gtk.Label()
     251        self._data_label_down.props.xalign = 0.0
     252        label_alignment = self._add_widget_with_padding(self._data_label_down)
     253        self.connection_info_box.pack_start(label_alignment)
     254        self._data_label_down.show()
    240255        label_alignment.show()
    241256
     257        self.info_box.pack_start(self.connection_info_box)
     258
    242259        self.info_box.show()
    243260        self.set_content(self.info_box)
    244261
     262        self.set_state(_GSM_STATE_NOT_READY)
     263
    245264    def _add_widget_with_padding(self, child, xalign=0, yalign=0.5):
    246265        alignment = gtk.Alignment(xalign=xalign, yalign=yalign,
    247266                                  xscale=1, yscale=0.33)
    class GsmPalette(Palette): 
    252271        alignment.add(child)
    253272        return alignment
    254273
    255     def set_state(self, state):
     274    def update_state(self, state, reason=0):
    256275        self._current_state = state
    257         self._update_label_and_text()
     276        self._update_label_and_text(reason)
    258277
    259     def _update_label_and_text(self):
     278    def _update_label_and_text(self, reason=0):
    260279        if self._current_state == _GSM_STATE_NOT_READY:
    261280            self._toggle_state_item.get_child().set_label('...')
    262281            self.props.secondary_text = _('Please wait...')
    263282
    264283        elif self._current_state == _GSM_STATE_DISCONNECTED:
    265             self._toggle_state_item.get_child().set_label(_('Connect'))
     284            if not self._failed_connection:
     285                self._toggle_state_item.get_child().set_label(_('Connect'))
    266286            self.props.secondary_text = _('Disconnected')
     287            icon = Icon(icon_name='dialog-ok', \
     288                            icon_size=gtk.ICON_SIZE_MENU)
     289            self._toggle_state_item.set_image(icon)
    267290
    268291        elif self._current_state == _GSM_STATE_CONNECTING:
    269292            self._toggle_state_item.get_child().set_label(_('Cancel'))
    270293            self.props.secondary_text = _('Connecting...')
     294            icon = Icon(icon_name='dialog-cancel', \
     295                            icon_size=gtk.ICON_SIZE_MENU)
     296            self._toggle_state_item.set_image(icon)
    271297
    272298        elif self._current_state == _GSM_STATE_CONNECTED:
     299            self._failed_connection = False
    273300            self._toggle_state_item.get_child().set_label(_('Disconnect'))
    274             self.props.secondary_text = _('Connected')
    275            
    276         elif self._current_state == _GSM_STATE_NEED_AUTH:
    277             self._toggle_state_item.get_child().set_label(_('Sim requires Pin/Puk'))
    278             self.props.secondary_text = _('Authentication Error')
     301            self.update_connection_time()
     302            icon = Icon(icon_name='media-eject', \
     303                            icon_size=gtk.ICON_SIZE_MENU)
     304            self._toggle_state_item.set_image(icon)
    279305           
     306        elif self._current_state == _GSM_STATE_FAILED:
     307            message_error = self._get_error_by_nm_reason(reason)
     308            self.add_alert(message_error[0], message_error[1])
    280309        else:
    281310            raise ValueError('Invalid GSM state while updating label and ' \
    282311                             'text, %s' % str(self._current_state))
    class GsmPalette(Palette): 
    285314        if self._current_state == _GSM_STATE_NOT_READY:
    286315            pass
    287316        elif self._current_state == _GSM_STATE_DISCONNECTED:
     317            self.error_title_label.hide()
     318            self.error_description_label.hide()
    288319            self.emit('gsm-connect')
    289320        elif self._current_state == _GSM_STATE_CONNECTING:
    290321            self.emit('gsm-disconnect')
    291322        elif self._current_state == _GSM_STATE_CONNECTED:
    292323            self.emit('gsm-disconnect')
    293         elif self._current_state == _GSM_STATE_NEED_AUTH:
    294             self.emit('gsm-disconnect')
    295324        else:
    296325            raise ValueError('Invalid GSM state while emitting signal, %s' % \
    297326                             str(self._current_state))
    298327
     328    def add_alert(self, error, suggestion):
     329        self._failed_connection = True
     330        self._toggle_state_item.get_child().set_label(_('Try connection again'))
     331
     332        title = _('Error: %s') % error
     333        self.error_title_label.set_markup('<b>%s</b>' % title)
     334        self.error_title_label.show()
     335
     336        message = _('Suggestion: %s') % suggestion
     337        self.error_description_label.set_text(message)
     338        self.error_description_label.show()
     339
     340    def update_connection_time(self, connection_time=None):
     341        if connection_time is not None:
     342            self.props.secondary_text = _('Connected for %s') % \
     343                    connection_time.strftime('%H:%M:%S')
     344        else:
     345            self.props.secondary_text = _('Connected for %s') % '00:00:00'
     346
     347    def update_stats(self, in_bytes, out_bytes):
     348        in_KBytes = in_bytes / 1024
     349        out_KBytes = out_bytes / 1024
     350        self._data_label_up.set_text(_("%d KB") % (out_KBytes))
     351        self._data_label_down.set_text(_("%d KB") % (in_KBytes))
     352
     353    def _get_error_by_nm_reason(self, reason):
     354        if reason in [network.NM_DEVICE_STATE_REASON_NO_SECRETS,
     355                      network.NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED]:
     356            message = _('Check your Pin/Puk configuration.')
     357        elif reason in [network.NM_DEVICE_STATE_REASON_PPP_DISCONNECT,
     358                        network.NM_DEVICE_STATE_REASON_PPP_FAILED]:
     359            message = _('Check your Access Point Name ' \
     360                            '(APN) configuration')
     361        elif reason in [network.NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER,
     362                        network.NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT]:
     363            message = _('Check the Number configuration.')
     364        elif reason == network.NM_DEVICE_STATE_REASON_CONFIG_FAILED:
     365            message = _('Check your configuration.')
     366        else:
     367            message = ''
     368        message_tuple = (network.get_error_by_reason(reason), message)
     369        return message_tuple
     370
    299371
    300372class WirelessDeviceView(ToolButton):
    301373
    class GsmDeviceView(TrayIcon): 
    704776                                        '/',
    705777                                        reply_handler=self.__connect_cb,
    706778                                        error_handler=self.__connect_error_cb)
     779        else:
     780            self._palette.add_alert(_('No GSM connection available.'), \
     781                                        _('Create a connection in the ' \
     782                                              'control panel.'))
    707783
    708784    def __connect_cb(self, active_connection):
    709785        logging.debug('Connected successfully to gsm device, %s',
    class GsmDeviceView(TrayIcon): 
    736812        raise RuntimeError('Error when disconnecting gsm device, %s' % error)
    737813
    738814    def __state_changed_cb(self, new_state, old_state, reason):
    739         logging.debug('State: %s to %s, reason %s', old_state, new_state, reason)
    740         self._update_state(int(new_state))
     815        logging.debug('State: %s to %s, reason %s', old_state,
     816                      new_state, reason)
     817        self._update_state(int(new_state), int(old_state), int(reason))
    741818
    742819    def __current_state_check_cb(self, properties):
    743         self._update_state(int(properties['State']))
     820        self._update_state(int(properties['State']), 0, 0)
    744821
    745822    def __current_state_check_error_cb(self, error):
    746823        raise RuntimeError('Error when checking gsm device state, %s' % error)
    747824
    748     def _update_state(self, state):
     825    def _update_state(self, state, old_state, reason):
    749826        gsm_state = None
    750827
    751828        if state is network.DEVICE_STATE_ACTIVATED:
    class GsmDeviceView(TrayIcon): 
    753830            connection = network.find_gsm_connection()
    754831            if connection is not None:
    755832                connection.set_connected()
    756                 self._connection_timestamp =  time.time() - \
     833                self._connection_timestamp = time.time() - \
    757834                        connection.get_settings().connection.timestamp
    758835                self._connection_time_handler = gobject.timeout_add_seconds( \
    759836                        1, self.__connection_timecount_cb)
    760                 self._update_stats(0, 0)
    761                 self._update_connection_time()               
    762                 self._palette.info_box.show()
     837                self._palette.update_connection_time()
     838                self._palette.update_stats(0, 0)
     839                if self._palette is not None:
     840                    self._palette.connection_info_box.show()
    763841
    764842        elif state is network.DEVICE_STATE_DISCONNECTED:
    765843            gsm_state = _GSM_STATE_DISCONNECTED
    766844            self._connection_timestamp = 0
    767845            if self._connection_time_handler is not None:
    768846                gobject.source_remove(self._connection_time_handler)
    769             self._palette.info_box.hide()
     847            if self._palette is not None:
     848                self._palette.connection_info_box.hide()
    770849
    771850        elif state in [network.DEVICE_STATE_UNMANAGED,
    772851                       network.DEVICE_STATE_UNAVAILABLE,
    class GsmDeviceView(TrayIcon): 
    775854
    776855        elif state in [network.DEVICE_STATE_PREPARE,
    777856                       network.DEVICE_STATE_CONFIG,
    778                        network.DEVICE_STATE_IP_CONFIG]:
     857                       network.DEVICE_STATE_IP_CONFIG,
     858                       network.DEVICE_STATE_NEED_AUTH]:
    779859            gsm_state = _GSM_STATE_CONNECTING
    780            
    781         elif state in [network.DEVICE_STATE_NEED_AUTH]:
    782             gsm_state = _GSM_STATE_NEED_AUTH
    783            
     860
     861        elif state == network.DEVICE_STATE_FAILED:
     862            gsm_state = _GSM_STATE_FAILED
     863
    784864        if self._palette is not None:
    785             self._palette.set_state(gsm_state)
     865            self._palette.update_state(gsm_state, reason)
    786866
    787867    def disconnect(self):
    788868        self._bus.remove_signal_receiver(self.__state_changed_cb,
    class GsmDeviceView(TrayIcon): 
    791871                                         dbus_interface=_NM_DEVICE_IFACE)
    792872
    793873    def __ppp_stats_changed_cb(self, in_bytes, out_bytes):
    794         self._update_stats(in_bytes, out_bytes)
    795 
    796     def _update_stats(self, in_bytes, out_bytes):
    797         in_KBytes = in_bytes / 1024
    798         out_KBytes = out_bytes / 1024
    799         text = _("Data sent %d KB / received %d KB") % (out_KBytes, in_KBytes)
    800         self._palette.data_label.set_text(text)
     874        self._palette.update_stats(in_bytes, out_bytes)
    801875
    802876    def __connection_timecount_cb(self):
    803877        self._connection_timestamp = self._connection_timestamp + 1
    804         self._update_connection_time()
     878        connection_time = \
     879            datetime.datetime.fromtimestamp(self._connection_timestamp)
     880        self._palette.update_connection_time(connection_time)
    805881        return True
    806882
    807     def _update_connection_time(self):
    808         connection_time = datetime.datetime.fromtimestamp( \
    809                 self._connection_timestamp)
    810         text = _("Connection time ") + connection_time.strftime('%H : %M : %S')
    811         self._palette.connection_time_label.set_text(text)
    812883
    813884class WirelessDeviceObserver(object):
    814885    def __init__(self, device, tray):
  • src/jarabe/model/network.py

    diff --git a/src/jarabe/model/network.py b/src/jarabe/model/network.py
    index cd0d46e..66d86d8 100644
    a b  
    1818# along with this program; if not, write to the Free Software
    1919# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    2020
     21from gettext import gettext as _
    2122import logging
    2223import os
    2324import time
    NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0 
    5556NM_ACTIVE_CONNECTION_STATE_ACTIVATING = 1
    5657NM_ACTIVE_CONNECTION_STATE_ACTIVATED = 2
    5758
     59
     60NM_DEVICE_STATE_REASON_UNKNOWN = 0
     61NM_DEVICE_STATE_REASON_NONE = 1
     62NM_DEVICE_STATE_REASON_NOW_MANAGED = 2
     63NM_DEVICE_STATE_REASON_NOW_UNMANAGED = 3
     64NM_DEVICE_STATE_REASON_CONFIG_FAILED = 4
     65NM_DEVICE_STATE_REASON_CONFIG_UNAVAILABLE = 5
     66NM_DEVICE_STATE_REASON_CONFIG_EXPIRED = 6
     67NM_DEVICE_STATE_REASON_NO_SECRETS = 7
     68NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT = 8
     69NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED = 9
     70NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED = 10
     71NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT = 11
     72NM_DEVICE_STATE_REASON_PPP_START_FAILED = 12
     73NM_DEVICE_STATE_REASON_PPP_DISCONNECT = 13
     74NM_DEVICE_STATE_REASON_PPP_FAILED = 14
     75NM_DEVICE_STATE_REASON_DHCP_START_FAILED = 15
     76NM_DEVICE_STATE_REASON_DHCP_ERROR = 16
     77NM_DEVICE_STATE_REASON_DHCP_FAILED = 17
     78NM_DEVICE_STATE_REASON_SHARED_START_FAILED = 18
     79NM_DEVICE_STATE_REASON_SHARED_FAILED = 19
     80NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED = 20
     81NM_DEVICE_STATE_REASON_AUTOIP_ERROR = 21
     82NM_DEVICE_STATE_REASON_AUTOIP_FAILED = 22
     83NM_DEVICE_STATE_REASON_MODEM_BUSY = 23
     84NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE = 24
     85NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER = 25
     86NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT = 26
     87NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED = 27
     88NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED = 28
     89NM_DEVICE_STATE_REASON_GSM_APN_FAILED = 29
     90NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING = 30
     91NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED = 31
     92NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT = 32
     93NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED = 33
     94NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED = 34
     95NM_DEVICE_STATE_REASON_FIRMWARE_MISSING = 35
     96NM_DEVICE_STATE_REASON_REMOVED = 36
     97NM_DEVICE_STATE_REASON_SLEEPING = 37
     98NM_DEVICE_STATE_REASON_CONNECTION_REMOVED = 38
     99NM_DEVICE_STATE_REASON_USER_REQUESTED = 39
     100NM_DEVICE_STATE_REASON_CARRIER = 40
     101
    58102NM_802_11_AP_FLAGS_NONE = 0x00000000
    59103NM_802_11_AP_FLAGS_PRIVACY = 0x00000001
    60104
    GSM_PUK_PATH = '/desktop/sugar/network/gsm/puk' 
    100144_nm_settings = None
    101145_conn_counter = 0
    102146
     147_nm_device_state_reason_description = None
     148
     149def get_error_by_reason(reason):
     150    global _nm_device_state_reason_description
     151
     152    if _nm_device_state_reason_description is None:
     153        _nm_device_state_reason_description = {
     154            NM_DEVICE_STATE_REASON_UNKNOWN: \
     155                _("The reason for the device state change \ is unknown."),
     156            NM_DEVICE_STATE_REASON_NONE: \
     157                _("The state change is normal."),
     158            NM_DEVICE_STATE_REASON_NOW_MANAGED: \
     159                _("The device is now managed."),
     160            NM_DEVICE_STATE_REASON_NOW_UNMANAGED: \
     161                _("The device is no longer managed."),
     162            NM_DEVICE_STATE_REASON_CONFIG_FAILED: \
     163                _("The device could not be readied for configuration."),
     164            NM_DEVICE_STATE_REASON_CONFIG_UNAVAILABLE : \
     165                _("IP configuration could not be reserved " \
     166                      "(no available address, timeout, etc)."),
     167            NM_DEVICE_STATE_REASON_CONFIG_EXPIRED : \
     168                _("The IP configuration is no longer valid."),
     169            NM_DEVICE_STATE_REASON_NO_SECRETS : \
     170                _("Secrets were required, but not provided."),
     171            NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT : \
     172                _("The 802.1X supplicant disconnected from "\
     173                      "the access point or authentication server."),
     174            NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED : \
     175                _("Configuration of the 802.1X supplicant failed."),
     176            NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED : \
     177                _("The 802.1X supplicant quit or failed unexpectedly."),
     178            NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT : \
     179                _("The 802.1X supplicant took too long to authenticate."),
     180            NM_DEVICE_STATE_REASON_PPP_START_FAILED : \
     181                _("The PPP service failed to start within the allowed time."),
     182            NM_DEVICE_STATE_REASON_PPP_DISCONNECT : \
     183                _("The PPP service disconnected unexpectedly."),
     184            NM_DEVICE_STATE_REASON_PPP_FAILED : \
     185                _("The PPP service quit or failed unexpectedly."),
     186            NM_DEVICE_STATE_REASON_DHCP_START_FAILED : \
     187                _("The DHCP service failed to start within the allowed time."),
     188            NM_DEVICE_STATE_REASON_DHCP_ERROR : \
     189                _("The DHCP service reported an unexpected error."),
     190            NM_DEVICE_STATE_REASON_DHCP_FAILED : \
     191                _("The DHCP service quit or failed unexpectedly."),
     192            NM_DEVICE_STATE_REASON_SHARED_START_FAILED : \
     193                _("The shared connection service failed to start."),
     194            NM_DEVICE_STATE_REASON_SHARED_FAILED : \
     195                _("The shared connection service quit or " \
     196                      "failed unexpectedly."),
     197            NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED : \
     198                _("The AutoIP service failed to start."),
     199            NM_DEVICE_STATE_REASON_AUTOIP_ERROR : \
     200                _("The AutoIP service reported an unexpected error."),
     201            NM_DEVICE_STATE_REASON_AUTOIP_FAILED : \
     202                _("The AutoIP service quit or failed unexpectedly."),
     203            NM_DEVICE_STATE_REASON_MODEM_BUSY : \
     204                _("Dialing failed because the line was busy."),
     205            NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE : \
     206                _("Dialing failed because there was no dial tone."),
     207            NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER : \
     208                _("Dialing failed because there was no carrier."),
     209            NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT : \
     210                _("Dialing timed out."),
     211            NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED : \
     212                _("Dialing failed."),
     213            NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED : \
     214                _("Modem initialization failed."),
     215            NM_DEVICE_STATE_REASON_GSM_APN_FAILED : \
     216                _("Failed to select the specified GSM APN."),
     217            NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING : \
     218                _("Not searching for networks."),
     219            NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED : \
     220                _("Network registration was denied."),
     221            NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT : \
     222                _("Network registration timed out."),
     223            NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED : \
     224                _("Failed to register with the requested GSM network."),
     225            NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED : \
     226                _("PIN check failed."),
     227            NM_DEVICE_STATE_REASON_FIRMWARE_MISSING : \
     228                _("Necessary firmware for the device may be missing."),
     229            NM_DEVICE_STATE_REASON_REMOVED : \
     230                _("The device was removed."),
     231            NM_DEVICE_STATE_REASON_SLEEPING : \
     232                _("NetworkManager went to sleep."),
     233            NM_DEVICE_STATE_REASON_CONNECTION_REMOVED : \
     234                _("The device's active connection was removed " \
     235                      "or disappeared."),
     236            NM_DEVICE_STATE_REASON_USER_REQUESTED : \
     237                _("A user or client requested the disconnection."),
     238            NM_DEVICE_STATE_REASON_CARRIER : \
     239                _("The device's carrier/link changed.")}
     240
     241    return _nm_device_state_reason_description[reason]
     242
     243
    103244
    104245def frequency_to_channel(frequency):
    105246    """Returns the channel matching a given radio channel frequency. If a
    class NMSettingsConnection(dbus.service.Object): 
    480621                         in_signature='sasb', out_signature='a{sa{sv}}')
    481622    def GetSecrets(self, setting_name, hints, request_new, reply, error):
    482623        logging.debug('Secrets requested for connection %s request_new=%s',
    483             self.path, request_new)
    484         if request_new or self._secrets is None:
    485             # request_new is for example the case when the pw on the AP changes
    486             response = SecretsResponse(self, reply, error)
    487             try:
    488                 self.secrets_request.send(self, response=response)
    489             except Exception:
    490                 logging.exception('Error requesting the secrets via dialog')
     624                      self.path, request_new)
     625        if self._settings.connection.type is not NM_CONNECTION_TYPE_GSM:
     626            if request_new or self._secrets is None:
     627                # request_new is for example the case when the pw on the AP changes
     628                response = SecretsResponse(self, reply, error)
     629                try:
     630                    self.secrets_request.send(self, response=response)
     631                except Exception:
     632                    logging.exception('Error requesting the secrets via dialog')
     633            else:
     634                reply(self._secrets.get_dict())
    491635        else:
    492             reply(self._secrets.get_dict())
    493 
     636            if not request_new:
     637                reply(self._secrets.get_dict())
     638            else:
     639                raise Exception('The stored GSM secret has already been supplied ')
    494640
    495641class AccessPoint(gobject.GObject):
    496642    __gsignals__ = {