--- pyanaconda/ui/gui/spokes/network.py | 802 ++++++++++++++++++++++++++++++++++- 1 files changed, 799 insertions(+), 3 deletions(-) diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py index a04f05c..6ded5fc 100644 --- a/pyanaconda/ui/gui/spokes/network.py +++ b/pyanaconda/ui/gui/spokes/network.py @@ -1,4 +1,4 @@ -# Installation source spoke classes +# Network configuration spoke classes # # Copyright (C) 2011 Red Hat, Inc. # @@ -20,7 +20,28 @@ # # TODO: + +# - move callback connection to populate? +# - more info on devices in list and notebook header +# -> another UI? + # - which type of spoke or category? +# - Automatically reconnecting wifi after failure +# https://bugzilla.redhat.com/show_bug.cgi?id=712778#c1 +# - We don't give reason for unavailable (firmware/, cable) +# - secrets agent - use nm_applet? +# see we_dont_have_nm_applet_as_secrets_agent +# - proxy support +# - operation modes - panel's property PROP_ARGV (CmdlineOperation) +# is it relevant for us? +# - expand for device list +# - nm_utils_escape_ssid +# - panel_cellrenderer_mode ? +# - callbacks on NM_CLIENT_MANAGER_RUNNING, NM_CLIENT_ACTIVE_CONNECTIONS? +# - ap selection combobox as anaconda-widget? (with renderers and stuff) +# - support connection to hidden network (ap-other) +# - fill ksdata (from ifcfg files!) +# - device_is_stored from gi.repository import Gtk, AnacondaWidgets @@ -28,8 +49,161 @@ from pyanaconda.ui.gui import UIObject from pyanaconda.ui.gui.spokes import NormalSpoke from pyanaconda.ui.gui.categories.software import SoftwareCategory +from gi.repository import GLib, GObject, Pango, Gio, NetworkManager, NMClient +import dbus +import socket +import subprocess +import struct +import time +from dbus.mainloop.glib import DBusGMainLoop +dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + +import ctypes +ctypes.cdll.LoadLibrary("libnm-util.so.2") +nm_utils = ctypes.CDLL("libnm-util.so.2") + +import gettext +_ = lambda x: gettext.ldgettext("anaconda", x) +P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z) + +# These are required due for dbus API use (we need it because of see NM_GI_BUGS) +NM_SERVICE = "org.freedesktop.NetworkManager" +NM_MANAGER_PATH = "/org/freedesktop/NetworkManager" +NM_SETTINGS_PATH = "/org/freedesktop/NetworkManager/Settings" +NM_MANAGER_IFACE = "org.freedesktop.NetworkManager" +NM_SETTINGS_IFACE = "org.freedesktop.NetworkManager.Settings" +NM_CONNECTION_IFACE = "org.freedesktop.NetworkManager.Settings.Connection" +NM_DEVICE_IFACE = "org.freedesktop.NetworkManager.Device" +NM_802_11_AP_FLAGS_PRIVACY = 0x1 +NM_802_11_AP_SEC_NONE = 0x0 +NM_802_11_AP_SEC_KEY_MGMT_802_1X = 0x200 +DBUS_PROPS_IFACE = "org.freedesktop.DBus.Properties" + +def getNMObjProperty(object, nm_iface_suffix, property): + props_iface = dbus.Interface(object, DBUS_PROPS_IFACE) + return props_iface.Get("org.freedesktop.NetworkManager"+nm_iface_suffix, + property) + + +DEVICES_COLUMN_OBJECT = 3 + +# TODO: We don't give reason for unavailable (firmware/, cable) +localized_string_of_device_state = { + NetworkManager.DeviceState.UNKNOWN : _("Status unknown"), + NetworkManager.DeviceState.UNMANAGED : _("Unmanaged"), + NetworkManager.DeviceState.UNAVAILABLE : _("Unavailable"), + NetworkManager.DeviceState.DISCONNECTED : _("Disconnected"), + NetworkManager.DeviceState.PREPARE : _("Connecting"), + NetworkManager.DeviceState.CONFIG : _("Connecting"), + NetworkManager.DeviceState.IP_CONFIG : _("Connecting"), + NetworkManager.DeviceState.IP_CHECK : _("Connecting"), + NetworkManager.DeviceState.NEED_AUTH : _("Authentication required"), + NetworkManager.DeviceState.ACTIVATED : _("Connected"), + NetworkManager.DeviceState.DEACTIVATING : _("Disconnecting"), + NetworkManager.DeviceState.FAILED : _("Connection failed"), +} + +configuration_of_disconnected_devices_allowed = True +# it is not in gnome-control-center but it makes sense +# for installer +# https://bugzilla.redhat.com/show_bug.cgi?id=704119 + +we_dont_have_nm_applet_as_secrets_agent = True +# so we have to disconnect from former ap before trying +# to connect to new one bound to fail due to no secrets + __all__ = ["NetworkSpoke"] +class CellRendererSignal(Gtk.CellRendererPixbuf): + + __gtype_name__ = "CellRendererSignal" + __gproperties__ = { + "signal": (GObject.TYPE_UINT, + "Signal", "Signal", + 0, GObject.G_MAXUINT, 0, + GObject.PARAM_READWRITE), + } + + def __init__(self): + Gtk.CellRendererPixbuf.__init__(self) + self.signal = 0 + + + def do_get_property(self, property): + if property.name == 'signal': + return self.signal + else: + raise AttributeError, 'unknown property %s' % property.name + + def do_set_property(self, property, value): + if property.name == 'signal': + self.signal = value + self._set_icon_name(value) + else: + raise AttributeError, 'unknown property %s' % property.name + + def _set_icon_name(self, value): + + if value == 0: + self.set_property("gicon", None) + + if value < 20: + icon_name = "network-wireless-signal-none-symbolic" + elif value < 40: + icon_name = "network-wireless-signal-weak-symbolic" + elif value < 50: + icon_name = "network-wireless-signal-ok-symbolic" + elif value < 80: + icon_name = "network-wireless-signal-good-symbolic" + else: + icon_name = "network-wireless-signal-excellent-symbolic" + + icon = Gio.ThemedIcon.new_with_default_fallbacks(icon_name) + self.set_property("gicon", icon) + + +NM_AP_SEC_UNKNOWN = 0 +NM_AP_SEC_NONE = 1 +NM_AP_SEC_WEP = 2 +NM_AP_SEC_WPA = 3 +NM_AP_SEC_WPA2 = 4 + +class CellRendererSecurity(Gtk.CellRendererPixbuf): + + __gtype_name__ = "CellRendererSecurity" + __gproperties__ = { + "security": (GObject.TYPE_UINT, + "Security", "Security", + 0, GObject.G_MAXUINT, 0, + GObject.PARAM_READWRITE), + } + + def __init__(self): + Gtk.CellRendererPixbuf.__init__(self) + self.security = NM_AP_SEC_UNKNOWN + self.icon_name = "" + + def do_get_property(self, property): + if property.name == 'security': + return self.security + else: + raise AttributeError, 'unknown property %s' % property.name + + def do_set_property(self, property, value): + if property.name == 'security': + self.security = value + self._set_icon_name(value) + else: + raise AttributeError, 'unknown property %s' % property.name + + def _set_icon_name(self, security): + self.icon_name = "" + if security not in (NM_AP_SEC_NONE, NM_AP_SEC_UNKNOWN): + self.icon_name = "network-wireless-encrypted-symbolic" + + self.set_property("icon-name", self.icon_name) + + class NetworkSpoke(NormalSpoke): builderObjects = ["networkWindow"] mainWidgetName = "networkWindow" @@ -37,12 +211,110 @@ class NetworkSpoke(NormalSpoke): category = SoftwareCategory + supported_device_types = [ + NetworkManager.DeviceType.ETHERNET, + NetworkManager.DeviceType.WIFI, + ] + def __init__(self, *args, **kwargs): NormalSpoke.__init__(self, *args, **kwargs) + self.builder.add_from_file("/usr/share/gnome-control-center/ui/network.ui") parent = self.builder.get_object("networkWindow-actionArea") self.builder.get_object("vbox1").reparent(parent) + # these buttons are only for vpn and proxy + self.builder.get_object("add_toolbutton").set_sensitive(False) + self.builder.get_object("remove_toolbutton").set_sensitive(False) + + # or use set_no_show_all() and hide()? + self.builder.get_object("hbox_1").destroy() + self.builder.get_object("start_hotspot_button").destroy() + self.builder.get_object("stop_hotspot_button").destroy() + self.builder.get_object("heading_hotspot_network_name").destroy() + self.builder.get_object("heading_hotspot_security_key").destroy() + self.builder.get_object("label_hotspot_network_name").destroy() + self.builder.get_object("label_hotspot_security_key").destroy() + self.builder.get_object("devices_toolbar").destroy() + self.builder.get_object("button_unlock").set_sensitive(False) + self.builder.get_object("hbox54").destroy() + + self.builder.get_object("notebook_types").set_show_tabs(False) + + self._refresh_idle = None + # to prevent UI update signals races + self._updating_device = False + + self.client = NMClient.Client.new() + self.remote_settings = NMClient.RemoteSettings() + + # devices list + # limited to wired and wireless + treeview = self.builder.get_object("treeview_devices") + self._add_device_columns(treeview) + devices_store = self.builder.get_object("liststore_devices") + devices_store.set_sort_column_id(2, Gtk.SortType.ASCENDING) + selection = treeview.get_selection() + selection.set_mode(Gtk.SelectionMode.BROWSE) + selection.connect("changed", self.on_device_selection_changed) + + # wireless APs list + combobox = self.builder.get_object("combobox_wireless_network_name") + self._add_ap_icons(combobox) + model = combobox.get_model() + model.set_sort_column_id(2, Gtk.SortType.ASCENDING) + combobox.connect("changed", self.on_wireless_ap_changed_cb) + + # NM Client + self.client.connect("device-added", self.on_device_added) + self.client.connect("device-removed", self.on_device_removed) + # TODO: perhaps not in anaconda + #self.client.connect("notify::%s" % NMClient.CLIENT_MANAGER_RUNNING, + # self._manager_running_cb) + # TODO (active_connections_changed) + #self.client.connect("notify::%s" % NMClient.CLIENT_ACTIVE_CONNECTIONS, + # self.on_active_connections_changed) + + self.builder.get_object("device_wired_off_switch").connect("notify::active", + self.on_device_off_toggled) + self.builder.get_object("device_wireless_off_switch").connect("notify::active", + self.on_device_off_toggled) + # TODO + #self.client.connect("notify::%s" % NMClient.CLIENT_WIRELESS_ENABLED, + # self._wireless_enabled_toggled) + + self.builder.get_object("button_wired_options").connect("clicked", + self.on_edit_connection) + self.builder.get_object("button_wireless_options").connect("clicked", + self.on_edit_connection) + + + def _add_ap_icons(self, combobox): + cell = CellRendererSecurity() + cell.set_padding(4, 0) + combobox.pack_start(cell, False) + combobox.add_attribute(cell, "security", 5) + + cell = CellRendererSignal() + cell.set_padding(4, 0) + #cell.set_property("xalign", 1.0) + combobox.pack_start(cell, False) + combobox.add_attribute(cell, "signal", 3) + + def _add_device_columns(self, treeview): + rnd = Gtk.CellRendererPixbuf() + rnd.set_property("stock-size", Gtk.IconSize.DND) + # TODO Gtk3 icon-name? (also at other places) + col = Gtk.TreeViewColumn("Icon", rnd, **{"icon-name":0}) + treeview.append_column(col) + + rnd = Gtk.CellRendererText() + rnd.set_property("wrap-mode", Pango.WrapMode.WORD) + col = Gtk.TreeViewColumn("Text", rnd, markup=2) + col.set_sort_column_id(2) + col.set_expand(True) + treeview.append_column(col) + def apply(self): pass @@ -64,13 +336,537 @@ class NetworkSpoke(NormalSpoke): self._grabObjects() + for device in self.client.get_devices(): + self.add_device(device) + + treeview = self.builder.get_object("treeview_devices") + devices_store = self.builder.get_object("liststore_devices") + selection = treeview.get_selection() + selection.select_iter(devices_store.get_iter_first()) + def setup(self): NormalSpoke.setup(self) # Signal handlers. - def on_configure_clicked(self, button): - pass + def on_device_selection_changed(self, *args): + print "DBG: on_device_selection_changed" + self.refresh_ui() + + def on_device_state_changed(self, *args): + print "DBG: on_device_state_changed" + self.refresh_ui() + + def on_active_connections_changed(self, *args): + print "DBG: on_active_connections_changed" + self.refresh_ui() + + def on_wireless_ap_changed_cb(self, combobox, *args): + print "DBG: on_wireles_ap_changed_cb" + + if self._updating_device: + return + iter = combobox.get_active_iter() + if not iter: + return + + print "DBG: on_wireless_ap_changed_cb was not ignored" + + device = self.selected_device() + ap_obj_path, ssid_target = combobox.get_model().get(iter, 0, 1) + if ap_obj_path == "ap-other...": + print "DBG: connection to hidden network not supported (nm-applet)" + return + + if we_dont_have_nm_applet_as_secrets_agent: + if self.find_active_connection_for_device(device): + # TODO we should pass callback and block until really disconnected? + # or is wireless reconnection stuff solved in NM? TEST! + device.disconnect(None, None) + + con = self.find_connection_for_device(device, ssid_target) + if con: + self.client.activate_connection(con, device, + None, None, None) + else: + self.client.add_and_activate_connection(None, device, ap_obj_path, + None, None) + + def on_device_added(self, device): + self.add_device(device) + + def on_device_removed(self, device): + self.remove_device(device) + + def on_edit_connection(self, *args): + device = self.selected_device() + if not device: + return + + con = self.find_active_connection_for_device(device) + if not con and configuration_of_disconnected_devices_allowed: + if device.get_device_type() == NetworkManager.DeviceType.WIFI: + combobox = self.builder.get_object("combobox_wireless_network_name") + iter = combobox.get_active_iter() + if not iter: + return + ap_obj_path, ssid = combobox.get_model().get(iter, 0, 1) + + con = self.find_connection_for_device(device, ssid=None) + + if con: + uuid = con.get_uuid() + else: + print "DBG: no active connection to be edited found" + return + + # TODO: blocking? logging? + # subprocess.call(["nm-connection-editor", "--edit", "%s" % uuid]) + subprocess.Popen(["nm-connection-editor", "--edit", "%s" % uuid]) + + def on_device_off_toggled(self, switch, *args): + if self._updating_device: + print "DBG: off switch ignored" + return + + print "DBG: off switch" + active = switch.get_active() + + device = self.selected_device() + + dev_type = device.get_device_type() + if dev_type == NetworkManager.DeviceType.ETHERNET: + if active: + cons = self.remote_settings.list_connections() + dev_cons = device.filter_connections(cons) + if dev_cons: + self.client.activate_connection(dev_cons[0], device, + None, None, None) + else: + self.client.add_and_activate_connection(None, device, None, + None, None) + else: + device.disconnect(None, None) + elif dev_type == NetworkManager.DeviceType.WIFI: + self.client.wireless_set_enabled(active) def on_back_clicked(self, window): self.window.hide() Gtk.main_quit() + + def selected_device(self): + selection = self.builder.get_object("treeview_devices").get_selection() + (model, iter) = selection.get_selected() + if not iter: + return None + return model.get(iter, DEVICES_COLUMN_OBJECT)[0] + + def find_connection_for_device(self, device, ssid=None): + dev_hwaddr = device.get_hw_address() + cons = self.remote_settings.list_connections() + for con in cons: + con_type = con.get_setting_connection().get_connection_type() + if con_type == NetworkManager.SETTING_WIRED_SETTING_NAME: + settings = con.get_setting_wired() + elif con_type == NetworkManager.SETTING_WIRELESS_SETTING_NAME: + settings = con.get_setting_wireless() + if ssid and ssid != settings.get_ssid(): + continue + else: + continue + con_hwaddr = ":".join("%02X" % ord(bytechar) for bytechar in settings.get_mac_address()) + if con_hwaddr == dev_hwaddr: + return con + return None + + def find_active_connection_for_device(self, device): + cons = self.client.get_active_connections() + for con in cons: + if con.get_devices()[0] is device: + return self.remote_settings.get_connection_by_path(con.get_connection()) + return None + + def _device_is_stored(self, nm_device): + """TODO check that device with Udi of nm_device is already in + liststore""" + return False + + def add_device(self, device): + print "DBG: adding device %s" % device + + if self._device_is_stored(device): + print "DBG: device already stored" + return + + if device.get_device_type() not in self.supported_device_types: + return + + device.connect("state-changed", self.on_device_state_changed) + + self.builder.get_object("liststore_devices").append([ + self._dev_icon_name(device), + self._dev_type_sort_value(device), + self._dev_title(device), + device, + ]) + + def _dev_icon_name(self, device): + icon_name = "" + dev_type = device.get_device_type() + if dev_type == NetworkManager.DeviceType.ETHERNET: + if device.get_state() == NetworkManager.DeviceState.UNAVAILABLE: + icon_name = "network-wired-disconnected" + else: + icon_name = "network-wired" + elif dev_type == NetworkManager.DeviceType.WIFI: + icon_name = "network-wireless" + + return icon_name + + def _dev_type_sort_value(self, device): + dev_type = device.get_device_type() + if dev_type == NetworkManager.DeviceType.ETHERNET: + str = "1" + elif dev_type == NetworkManager.DeviceType.WIFI: + str = "2" + else: + str = "3" + return str + + def _dev_title(self, device): + #return '<span hsize="large">%s</span>' % self._dev_type_str(device) + return self._dev_type_str(device) + + def _dev_type_str(self, device): + dev_type = device.get_device_type() + if dev_type == NetworkManager.DeviceType.UNKNOWN: + title = _("Unknown") + elif dev_type == NetworkManager.DeviceType.ETHERNET: + title = _("Ethernet") + elif dev_type == NetworkManager.DeviceType.WIFI: + title = _("Wireless") + else: + title = "" + return title + + def remove_device(self, device): + # This should not concern wifi and ethernet devices, + # just virtual devices e.g. vpn probably + # TODO test!, remove perhaps + model = self.builder.get_object("liststore_devices") + rows_to_remove = [] + for row in model: + if (device.get_udi() == row[DEVICES_COLUMN_OBJECT].get_udi()): + rows_to_remove.append(row) + for row in rows_to_remove: + del(row) + + def refresh_ui(self): + if self._refresh_idle: + print "DBG: refresh_ui_idle found" + return + time.sleep(0.3) + self._refresh_idle = GLib.idle_add(self.refresh_ui_idle) + print "DBG: refresh_ui_idle planned" + + def refresh_ui_idle(self): + print "DBG: refreshing ui" + self.refresh_device_ui(self.selected_device()) + self._refresh_idle = None + + def refresh_device_ui(self, device): + + notebook = self.builder.get_object("notebook_types") + + dev_type = device.get_device_type() + + if dev_type == NetworkManager.DeviceType.ETHERNET: + + dt = "wired" + notebook.set_current_page(0) + + self._refresh_header_ui(device, dt) + + speed = device.get_speed() + if device.get_state() == NetworkManager.DeviceState.UNAVAILABLE: + speed_str = None + elif speed: + speed_str = _("%d Mb/s") % speed + else: + speed_str = "" + self._set_device_info_value(dt, "speed", speed_str) + + self._set_device_info_value(dt, "mac", device.get_hw_address()) + + elif dev_type == NetworkManager.DeviceType.WIFI: + + dt = "wireless" + notebook.set_current_page(1) + + self._refresh_header_ui(device, dt) + + speed = device.get_bitrate() + if device.get_state() == NetworkManager.DeviceState.UNAVAILABLE: + speed_str = None + elif speed: + speed_str = _("%d Mb/s") % (speed / 1000) + else: + speed_str = "" + self._set_device_info_value(dt, "speed", speed_str) + + self._set_device_info_value(dt, "mac", device.get_hw_address()) + + if device.get_state() == NetworkManager.DeviceState.UNAVAILABLE: + ap_str = None + else: + active_ap = device.get_active_access_point() + if active_ap: + active_ap_dbus = dbus.SystemBus().get_object(NM_SERVICE, + active_ap.get_path()) + ap_str = self._ap_security_string_dbus(active_ap_dbus) + # TODO NM_GI_BUGS move to gi after fixed in NM + # - NetworkManager.80211ApFlags + # - active_ap.get_flags, get_wpa_flags, get_rsn_flags + #ap_str = self._ap_security_string(active_ap) + else: + ap_str = "" + + self._set_device_info_value(dt, "security", ap_str) + + if device.get_state() == NetworkManager.DeviceState.UNAVAILABLE: + self.builder.get_object("heading_wireless_network_name").hide() + self.builder.get_object("combobox_wireless_network_name").hide() + else: + self.builder.get_object("heading_wireless_network_name").show() + self.builder.get_object("combobox_wireless_network_name").show() + + store = self.builder.get_object("liststore_wireless_network") + self._updating_device = True + store.clear() + aps = self._get_strongest_unique_aps(device.get_access_points()) + for ap in aps: + active = active_ap and active_ap.get_path() == ap.get_path() + self._add_ap(ap, active) + # TODO: add access point other... + self._updating_device = False + + else: + print ("DBG: unsupported device type in the list!") + return + + # Only dhcp info is presented for ipv4, for static go to Options...? + + ipv4cfg = device.get_ip4_config() + if (ipv4cfg + and device.get_state() == NetworkManager.DeviceState.ACTIVATED): + addr = socket.inet_ntoa(struct.pack('L', + ipv4cfg.get_addresses()[0].get_address())) + self._set_device_info_value(dt, "ipv4", addr) + dnss = " ".join([socket.inet_ntoa(struct.pack('L', addr)) + for addr in ipv4cfg.get_nameservers()]) + self._set_device_info_value(dt, "dns", dnss) + gateway = socket.inet_ntoa(struct.pack('L', + ipv4cfg.get_addresses()[0].get_gateway())) + self._set_device_info_value(dt, "route", gateway) + if dt == "wired": + prefix = ipv4cfg.get_addresses()[0].get_prefix() + netmask = nm_utils.nm_utils_ip4_prefix_to_netmask(prefix) + netmask = socket.inet_ntoa(struct.pack('L', netmask)) + self._set_device_info_value(dt, "subnet", netmask) + else: + self._set_device_info_value(dt, "ipv4", None) + self._set_device_info_value(dt, "dns", None) + self._set_device_info_value(dt, "route", None) + if dt == "wired": + self._set_device_info_value(dt, "subnet", None) + + # TODO NM_GI_BUGS - segfaults on get_addres(), get_prefix() + ipv6_addr = None + ipv6cfg = device.get_ip6_config() + if (ipv6cfg + and device.get_state() == NetworkManager.DeviceState.ACTIVATED): + config = dbus.SystemBus().get_object(NM_SERVICE, ipv6cfg.get_path()) + addr, prefix, gw = getNMObjProperty(config, ".IP6Config", + "Addresses")[0] + ipv6_addr = socket.inet_ntop(socket.AF_INET6, "".join(str(byte) for byte in addr)) + self._set_device_info_value(dt, "ipv6", ipv6_addr) + + if ipv4cfg and ipv6_addr: + self.builder.get_object("heading_%s_ipv4" % dt).set_label(_("IPv4 Address")) + self.builder.get_object("heading_%s_ipv6" % dt).set_label(_("IPv6 Address")) + elif ipv4cfg: + self.builder.get_object("heading_%s_ipv4" % dt).set_label(_("IP Address")) + elif ipv6_addr: + self.builder.get_object("heading_%s_ipv6" % dt).set_label(_("IP Address")) + + def _refresh_header_ui(self, device, dev_type_str): + + if dev_type_str == "wired": + # update icon according to device status + img = self.builder.get_object("image_wired_device") + img.set_from_icon_name(self._dev_icon_name(device), Gtk.IconSize.DIALOG) + + # TODO: is this necessary? Isn't it static from glade? + self.builder.get_object("label_%s_device" % dev_type_str).set_label( + self._dev_type_str(device)) + + state = device.get_state() + self.builder.get_object("label_%s_status" % dev_type_str).set_label( + localized_string_of_device_state.get(state, _("Status unknown (missing)"))) + + switch = self.builder.get_object("device_%s_off_switch" % dev_type_str) + if dev_type_str == "wired": + switch.set_visible(state not in (NetworkManager.DeviceState.UNAVAILABLE, + NetworkManager.DeviceState.UNMANAGED)) + self._updating_device = True + switch.set_active(state not in (NetworkManager.DeviceState.UNMANAGED, + NetworkManager.DeviceState.UNAVAILABLE, + NetworkManager.DeviceState.DISCONNECTED, + NetworkManager.DeviceState.DEACTIVATING, + NetworkManager.DeviceState.FAILED)) + self._updating_device = False + if not configuration_of_disconnected_devices_allowed: + self.builder.get_object("button_%s_options" % dev_type_str).set_sensitive(state == NetworkManager.DeviceState.ACTIVATED) + elif dev_type_str == "wireless": + switch.set_active(self.client.wireless_get_enabled()) + + def _set_device_info_value(self, dev_type_str, info, value_str): + heading = self.builder.get_object("heading_%s_%s" % (dev_type_str, info)) + value_label = self.builder.get_object("label_%s_%s" % (dev_type_str, info)) + if value_str is None: + heading.hide() + value_label.hide() + else: + heading.show() + value_label.show() + value_label.set_label(value_str) + + # TODO NM_GI_BUGS use glib methods for mode and security (dbus obj or nm obj?) + def _add_ap(self, ap, active=False): + ssid = ap.get_ssid() + if not ssid: + return + + # TODO NM_GI_BUGS + ap_dbus = dbus.SystemBus().get_object(NM_SERVICE, ap.get_path()) + mode = getNMObjProperty(ap_dbus, ".AccessPoint", "Mode") + + security = self._ap_security_dbus(ap) + + store = self.builder.get_object("liststore_wireless_network") + # the third column is for sorting + iter = store.append([ap.get_path(), + ssid, + ssid, + ap.get_strength(), + mode, + security]) + if active: + self.builder.get_object("combobox_wireless_network_name").set_active_iter(iter) + + def _get_strongest_unique_aps(self, access_points): + strongest_aps = {} + for ap in access_points: + ssid = ap.get_ssid() + if ssid in strongest_aps: + #print "DBG: found %s duplicate" % ssid + if ap.get_strength() > strongest_aps[ssid].get_strength(): + strongest_aps[ssid] = ap + #print "DBG: ...stronger" + else: + strongest_aps[ssid] = ap + #print "DBG: adding %s ap" % ssid + + return strongest_aps.values() + + # TODO NM_GI_BUGS fix as _ap_security_string + def _ap_security_dbus(self, ap): + if ap.get_path() == "/": + return NM_AP_SEC_UNKNOWN + + ap_dbus = dbus.SystemBus().get_object(NM_SERVICE, ap.get_path()) + flags = getNMObjProperty(ap_dbus, ".AccessPoint", "Flags") + wpa_flags = getNMObjProperty(ap_dbus, ".AccessPoint", "WpaFlags") + rsn_flags = getNMObjProperty(ap_dbus, ".AccessPoint", "RsnFlags") + + if (not (flags & NM_802_11_AP_FLAGS_PRIVACY) and + wpa_flags == NM_802_11_AP_SEC_NONE and + rsn_flags == NM_802_11_AP_SEC_NONE): + type = NM_AP_SEC_NONE + elif (flags & NM_802_11_AP_FLAGS_PRIVACY and + wpa_flags == NM_802_11_AP_SEC_NONE and + rsn_flags == NM_802_11_AP_SEC_NONE): + type = NM_AP_SEC_WEP + elif (not (flags & NM_802_11_AP_FLAGS_PRIVACY) and + wpa_flags != NM_802_11_AP_SEC_NONE and + rsn_flags != NM_802_11_AP_SEC_NONE): + type = NM_AP_SEC_WPA + else: + type = NM_AP_SEC_WPA2 + + return type + +## TODO NM_GI_BUGS - attribute starts with number +# def _ap_security_string(self, ap): +# if ap.object_path == "/": +# return "" +# +# flags = ap.get_flags() +# wpa_flags = ap.get_wpa_flags() +# rsn_flags = ap.get_rsn_flags() +# +# sec_str = "" +# +# if ((flags & NetworkManager.80211ApFlags.PRIVACY) and +# wpa_flags == NetworkManager.80211ApSecurityFlags.NONE and +# rsn_flags == NetworkManager.80211ApSecurityFlags.NONE): +# sec_str += "%s, " % _("WEP") +# +# if wpa_flags != NetworkManager.80211ApSecurityFlags.NONE: +# sec_str += "%s, " % _("WPA") +# +# if rsn_flags != NetworkManager.80211ApSecurityFlags.NONE: +# sec_str += "%s, " % _("WPA2") +# +# if ((wpa_flags & NetworkManager.80211ApSecurityFlags.KEY_MGMT_802_1X) or +# (rsn_flags & NetworkManager.80211ApSecurityFlags.KEY_MGMT_802_1X)): +# sec_str += "%s, " % _("Enterprise") +# +# if sec_str: +# sec_str = sec_str[:-2] +# else: +# sec_str = _("None") +# +# return sec_str + + def _ap_security_string_dbus(self, ap): + if ap.object_path == "/": + return "" + + flags = getNMObjProperty(ap, ".AccessPoint", "Flags") + wpa_flags = getNMObjProperty(ap, ".AccessPoint", "WpaFlags") + rsn_flags = getNMObjProperty(ap, ".AccessPoint", "RsnFlags") + + sec_str = "" + + if ((flags & NM_802_11_AP_FLAGS_PRIVACY) and + wpa_flags == NM_802_11_AP_SEC_NONE and + rsn_flags == NM_802_11_AP_SEC_NONE): + sec_str += "%s, " % _("WEP") + + if wpa_flags != NM_802_11_AP_SEC_NONE: + sec_str += "%s, " % _("WPA") + + if rsn_flags != NM_802_11_AP_SEC_NONE: + sec_str += "%s, " % _("WPA2") + + if ((wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) or + (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)): + sec_str += "%s, " % _("Enterprise") + + if sec_str: + sec_str = sec_str[:-2] + else: + sec_str = _("None") + + return sec_str + -- 1.7.7.5 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list