diff --git a/panels/network/Makefile.am b/panels/network/Makefile.am index 3f29af6c1..b16e24974 100644 --- a/panels/network/Makefile.am +++ b/panels/network/Makefile.am @@ -20,6 +20,8 @@ libnetwork_la_SOURCES = \ net-object.h \ net-device.c \ net-device.h \ + net-device-wifi.c \ + net-device-wifi.h \ net-device-wired.c \ net-device-wired.h \ net-device-mobile.c \ @@ -46,6 +48,7 @@ uidir = $(pkgdatadir)/ui dist_ui_DATA = \ network-proxy.ui \ network-vpn.ui \ + network-wifi.ui \ network-wired.ui \ network-mobile.ui \ network.ui diff --git a/panels/network/cc-network-panel.c b/panels/network/cc-network-panel.c index a5bac59ce..2aaee6a11 100644 --- a/panels/network/cc-network-panel.c +++ b/panels/network/cc-network-panel.c @@ -21,8 +21,6 @@ #include #include -#include -#include #include #include "cc-network-panel.h" @@ -30,30 +28,17 @@ #include "nm-remote-settings.h" #include "nm-client.h" #include "nm-device.h" -#include "nm-device-ethernet.h" #include "nm-device-modem.h" -#include "nm-device-wifi.h" -#include "nm-utils.h" -#include "nm-active-connection.h" -#include "nm-vpn-connection.h" -#include "nm-setting-wireless.h" -#include "nm-setting-ip4-config.h" -#include "nm-setting-ip6-config.h" -#include "nm-setting-connection.h" -#include "nm-setting-vpn.h" -#include "nm-setting-wireless.h" -#include "net-object.h" #include "net-device.h" -#include "net-device-wired.h" #include "net-device-mobile.h" +#include "net-device-wifi.h" +#include "net-device-wired.h" +#include "net-object.h" #include "net-proxy.h" #include "net-vpn.h" #include "panel-common.h" -#include "panel-cell-renderer-mode.h" -#include "panel-cell-renderer-signal.h" -#include "panel-cell-renderer-security.h" #include "network-dialogs.h" @@ -98,23 +83,6 @@ enum { PANEL_DEVICES_COLUMN_LAST }; -enum { - PANEL_WIRELESS_COLUMN_ID, - PANEL_WIRELESS_COLUMN_TITLE, - PANEL_WIRELESS_COLUMN_SORT, - PANEL_WIRELESS_COLUMN_STRENGTH, - PANEL_WIRELESS_COLUMN_MODE, - PANEL_WIRELESS_COLUMN_SECURITY, - PANEL_WIRELESS_COLUMN_ACTIVE, - PANEL_WIRELESS_COLUMN_LAST -}; - -enum { - PANEL_MOBILEBB_COLUMN_ID, - PANEL_MOBILEBB_COLUMN_TITLE, - PANEL_MOBILEBB_COLUMN_LAST -}; - enum { PROP_0, PROP_ARGV @@ -445,6 +413,8 @@ panel_add_device (CcNetworkPanel *panel, NMDevice *device) type = nm_device_get_device_type (device); if (type == NM_DEVICE_TYPE_BT) goto out; + if (type == NM_DEVICE_TYPE_WIMAX) + goto out; g_debug ("device %s type %i", nm_device_get_udi (device), @@ -460,6 +430,9 @@ panel_add_device (CcNetworkPanel *panel, NMDevice *device) case NM_DEVICE_TYPE_MODEM: device_g_type = NET_TYPE_DEVICE_MOBILE; break; + case NM_DEVICE_TYPE_WIFI: + device_g_type = NET_TYPE_DEVICE_WIFI; + break; default: device_g_type = NET_TYPE_DEVICE; break; @@ -606,966 +579,6 @@ panel_add_devices_columns (CcNetworkPanel *panel, GtkTreeView *treeview) gtk_tree_view_column_set_expand (column, TRUE); } -static void -panel_set_widget_data (CcNetworkPanel *panel, - const gchar *sub_pane, - const gchar *widget_suffix, - const gchar *value) -{ - gchar *heading_id; - gchar *label_id = NULL; - GtkWidget *heading; - GtkWidget *widget; - CcNetworkPanelPrivate *priv = panel->priv; - - /* hide the row if there is no value */ - heading_id = g_strdup_printf ("heading_%s_%s", sub_pane, widget_suffix); - label_id = g_strdup_printf ("label_%s_%s", sub_pane, widget_suffix); - heading = GTK_WIDGET (gtk_builder_get_object (priv->builder, heading_id)); - widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, label_id)); - if (heading == NULL || widget == NULL) { - g_critical ("no widgets %s, %s found", heading_id, label_id); - return; - } - g_free (heading_id); - g_free (label_id); - - if (value == NULL) { - gtk_widget_hide (heading); - gtk_widget_hide (widget); - } else { - /* there exists a value */ - gtk_widget_show (heading); - gtk_widget_show (widget); - gtk_label_set_label (GTK_LABEL (widget), value); - } -} - -static void -panel_set_widget_heading (CcNetworkPanel *panel, - const gchar *sub_pane, - const gchar *widget_suffix, - const gchar *heading) -{ - gchar *label_id = NULL; - GtkWidget *widget; - - label_id = g_strdup_printf ("heading_%s_%s", sub_pane, widget_suffix); - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, label_id)); - if (widget) - gtk_label_set_label (GTK_LABEL (widget), heading); - g_free (label_id); -} - -static guint -get_access_point_security (NMAccessPoint *ap) -{ - NM80211ApFlags flags; - NM80211ApSecurityFlags wpa_flags; - NM80211ApSecurityFlags rsn_flags; - guint type; - - flags = nm_access_point_get_flags (ap); - wpa_flags = nm_access_point_get_wpa_flags (ap); - rsn_flags = nm_access_point_get_rsn_flags (ap); - - if (!(flags & NM_802_11_AP_FLAGS_PRIVACY) && - wpa_flags == NM_802_11_AP_SEC_NONE && - rsn_flags == NM_802_11_AP_SEC_NONE) - type = NM_AP_SEC_NONE; - else if ((flags & NM_802_11_AP_FLAGS_PRIVACY) && - wpa_flags == NM_802_11_AP_SEC_NONE && - rsn_flags == NM_802_11_AP_SEC_NONE) - type = NM_AP_SEC_WEP; - else if (!(flags & NM_802_11_AP_FLAGS_PRIVACY) && - wpa_flags != NM_802_11_AP_SEC_NONE && - rsn_flags != NM_802_11_AP_SEC_NONE) - type = NM_AP_SEC_WPA; - else - type = NM_AP_SEC_WPA2; - - return type; -} - -static void -add_access_point (CcNetworkPanel *panel, NMAccessPoint *ap, NMAccessPoint *active, NMDevice *device) -{ - CcNetworkPanelPrivate *priv = panel->priv; - const GByteArray *ssid; - const gchar *ssid_text; - const gchar *object_path; - GtkListStore *liststore_wireless_network; - GtkTreeIter treeiter; - GtkWidget *widget; - gboolean is_active_ap; - - ssid = nm_access_point_get_ssid (ap); - if (ssid == NULL) - return; - ssid_text = nm_utils_escape_ssid (ssid->data, ssid->len); - - is_active_ap = active && nm_utils_same_ssid (ssid, nm_access_point_get_ssid (active), TRUE); - - liststore_wireless_network = GTK_LIST_STORE (gtk_builder_get_object (priv->builder, - "liststore_wireless_network")); - - object_path = nm_object_get_path (NM_OBJECT (ap)); - gtk_list_store_insert_with_values (liststore_wireless_network, - &treeiter, - -1, - PANEL_WIRELESS_COLUMN_ID, object_path, - PANEL_WIRELESS_COLUMN_TITLE, ssid_text, - PANEL_WIRELESS_COLUMN_SORT, ssid_text, - PANEL_WIRELESS_COLUMN_STRENGTH, nm_access_point_get_strength (ap), - PANEL_WIRELESS_COLUMN_MODE, nm_access_point_get_mode (ap), - PANEL_WIRELESS_COLUMN_SECURITY, get_access_point_security (ap), - PANEL_WIRELESS_COLUMN_ACTIVE, is_active_ap, - -1); - - /* is this what we're on already? */ - if (is_active_ap) { - widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, - "combobox_wireless_network_name")); - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (widget), &treeiter); - } - - if (priv->arg_operation == OPERATION_CONNECT_8021X && - g_strcmp0(priv->arg_device, nm_object_get_path (NM_OBJECT (device))) == 0 && - g_strcmp0(priv->arg_access_point, object_path) == 0) { - cc_network_panel_connect_to_8021x_network (panel, - priv->client, - priv->remote_settings, - device, - ap); - priv->arg_operation = OPERATION_NULL; /* done */ - } -} - -static void -add_access_point_other (CcNetworkPanel *panel) -{ - CcNetworkPanelPrivate *priv = panel->priv; - GtkListStore *liststore_wireless_network; - GtkTreeIter treeiter; - - liststore_wireless_network = GTK_LIST_STORE (gtk_builder_get_object (priv->builder, - "liststore_wireless_network")); - - gtk_list_store_append (liststore_wireless_network, &treeiter); - gtk_list_store_set (liststore_wireless_network, - &treeiter, - PANEL_WIRELESS_COLUMN_ID, "ap-other...", - /* TRANSLATORS: this is when the access point is not listed - * in the dropdown (or hidden) and the user has to select - * another entry manually */ - PANEL_WIRELESS_COLUMN_TITLE, C_("Wireless access point", "Other..."), - /* always last */ - PANEL_WIRELESS_COLUMN_SORT, "", - PANEL_WIRELESS_COLUMN_STRENGTH, 0, - PANEL_WIRELESS_COLUMN_MODE, NM_802_11_MODE_UNKNOWN, - PANEL_WIRELESS_COLUMN_SECURITY, NM_AP_SEC_UNKNOWN, - -1); -} - -static GPtrArray * -panel_get_strongest_unique_aps (const GPtrArray *aps) -{ - const GByteArray *ssid; - const GByteArray *ssid_tmp; - GPtrArray *aps_unique = NULL; - gboolean add_ap; - guint i; - guint j; - NMAccessPoint *ap; - NMAccessPoint *ap_tmp; - - /* we will have multiple entries for typical hotspots, just - * filter to the one with the strongest signal */ - aps_unique = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); - if (aps != NULL) - for (i = 0; i < aps->len; i++) { - ap = NM_ACCESS_POINT (g_ptr_array_index (aps, i)); - - /* Hidden SSIDs don't get shown in the list */ - ssid = nm_access_point_get_ssid (ap); - if (!ssid) - continue; - - add_ap = TRUE; - - /* get already added list */ - for (j=0; jlen; j++) { - ap_tmp = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, j)); - ssid_tmp = nm_access_point_get_ssid (ap_tmp); - g_assert (ssid_tmp); - - /* is this the same type and data? */ - if (nm_utils_same_ssid (ssid, ssid_tmp, TRUE)) { - - g_debug ("found duplicate: %s", - nm_utils_escape_ssid (ssid_tmp->data, - ssid_tmp->len)); - - /* the new access point is stronger */ - if (nm_access_point_get_strength (ap) > - nm_access_point_get_strength (ap_tmp)) { - g_debug ("removing %s", - nm_utils_escape_ssid (ssid_tmp->data, - ssid_tmp->len)); - g_ptr_array_remove (aps_unique, ap_tmp); - add_ap = TRUE; - } else { - add_ap = FALSE; - } - - break; - } - } - if (add_ap) { - g_debug ("adding %s", - nm_utils_escape_ssid (ssid->data, - ssid->len)); - g_ptr_array_add (aps_unique, g_object_ref (ap)); - } - } - return aps_unique; -} - -static gchar * -get_ap_security_string (NMAccessPoint *ap) -{ - NM80211ApSecurityFlags wpa_flags, rsn_flags; - NM80211ApFlags flags; - GString *str; - - flags = nm_access_point_get_flags (ap); - wpa_flags = nm_access_point_get_wpa_flags (ap); - rsn_flags = nm_access_point_get_rsn_flags (ap); - - str = g_string_new (""); - if ((flags & NM_802_11_AP_FLAGS_PRIVACY) && - (wpa_flags == NM_802_11_AP_SEC_NONE) && - (rsn_flags == NM_802_11_AP_SEC_NONE)) { - /* TRANSLATORS: this WEP WiFi security */ - g_string_append_printf (str, "%s, ", _("WEP")); - } - if (wpa_flags != NM_802_11_AP_SEC_NONE) { - /* TRANSLATORS: this WPA WiFi security */ - g_string_append_printf (str, "%s, ", _("WPA")); - } - if (rsn_flags != NM_802_11_AP_SEC_NONE) { - /* TRANSLATORS: this WPA WiFi security */ - g_string_append_printf (str, "%s, ", _("WPA2")); - } - if ((wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) || - (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { - /* TRANSLATORS: this Enterprise WiFi security */ - g_string_append_printf (str, "%s, ", _("Enterprise")); - } - if (str->len > 0) - g_string_set_size (str, str->len - 2); - else { - /* TRANSLATORS: this no (!) WiFi security */ - g_string_append (str, _("None")); - } - return g_string_free (str, FALSE); -} - -static gchar * -get_ipv4_config_address_as_string (NMIP4Config *ip4_config, const char *what) -{ - const GSList *list; - struct in_addr addr; - gchar *str = NULL; - gchar tmp[INET_ADDRSTRLEN]; - NMIP4Address *address; - - /* get address */ - list = nm_ip4_config_get_addresses (ip4_config); - if (list == NULL) - goto out; - - /* we only care about one address */ - address = list->data; - if (!strcmp (what, "address")) - addr.s_addr = nm_ip4_address_get_address (address); - else if (!strcmp (what, "gateway")) - addr.s_addr = nm_ip4_address_get_gateway (address); - else if (!strcmp (what, "netmask")) - addr.s_addr = nm_utils_ip4_prefix_to_netmask (nm_ip4_address_get_prefix (address)); - else - goto out; - - if (!inet_ntop (AF_INET, &addr, tmp, sizeof(tmp))) - goto out; - str = g_strdup (tmp); -out: - return str; -} - -static gchar * -get_ipv4_config_name_servers_as_string (NMIP4Config *ip4_config) -{ - const GArray *array; - GString *dns; - struct in_addr addr; - gchar tmp[INET_ADDRSTRLEN]; - int i; - - dns = g_string_new (NULL); - - array = nm_ip4_config_get_nameservers (ip4_config); - if (array) { - for (i = 0; i < array->len; i++) { - addr.s_addr = g_array_index (array, guint32, i); - if (inet_ntop (AF_INET, &addr, tmp, sizeof(tmp))) - g_string_append_printf (dns, "%s ", tmp); - } - } - - return g_string_free (dns, FALSE); -} - -static gchar * -get_ipv6_config_address_as_string (NMIP6Config *ip6_config) -{ - const GSList *list; - const struct in6_addr *addr; - gchar *str = NULL; - gchar tmp[INET6_ADDRSTRLEN]; - NMIP6Address *address; - - /* get address */ - list = nm_ip6_config_get_addresses (ip6_config); - if (list == NULL) - goto out; - - /* we only care about one address */ - address = list->data; - addr = nm_ip6_address_get_address (address); - if (addr == NULL) - goto out; - inet_ntop (AF_INET6, addr, tmp, sizeof(tmp)); - str = g_strdup (tmp); -out: - return str; -} - -static NMConnection * -find_connection_for_device (CcNetworkPanel *panel, - NMDevice *device) -{ - NetDevice *tmp; - NMConnection *connection; - tmp = g_object_new (NET_TYPE_DEVICE, - "client", panel->priv->client, - "remote-settings", panel->priv->remote_settings, - "nm-device", device, - NULL); - connection = net_device_get_find_connection (tmp); - g_object_unref (tmp); - return connection; -} - -static void -device_off_toggled (GtkSwitch *sw, - GParamSpec *pspec, - CcNetworkPanel *panel) -{ - NMDevice *device; - gboolean active; - NetObject *object; - - if (panel->priv->updating_device) - return; - - active = gtk_switch_get_active (sw); - - object = get_selected_object (panel); - if (NET_IS_DEVICE (object)) { - device = net_device_get_nm_device (NET_DEVICE (object)); - switch (nm_device_get_device_type (device)) { - case NM_DEVICE_TYPE_ETHERNET: - if (active) { - GSList *list, *filtered; - - /* look for an existing connection we can use */ - list = nm_remote_settings_list_connections (panel->priv->remote_settings); - filtered = nm_device_filter_connections (device, list); - if (filtered) { - nm_client_activate_connection (panel->priv->client, - (NMConnection *)filtered->data, - device, - NULL, - NULL, NULL); - } else { - nm_client_add_and_activate_connection (panel->priv->client, - NULL, - device, - NULL, - NULL, NULL); - } - - g_slist_free (list); - g_slist_free (filtered); - } else { - nm_device_disconnect (device, NULL, NULL); - } - break; - case NM_DEVICE_TYPE_WIFI: - nm_client_wireless_set_enabled (panel->priv->client, active); - break; - case NM_DEVICE_TYPE_WIMAX: - nm_client_wimax_set_enabled (panel->priv->client, active); - break; - case NM_DEVICE_TYPE_MODEM: - nm_client_wwan_set_enabled (panel->priv->client, active); - break; - default: ; - /* FIXME: handle other device types */ - } - } -} - -static void -wireless_enabled_toggled (NMClient *client, - GParamSpec *pspec, - CcNetworkPanel *panel) -{ - gboolean enabled; - GtkSwitch *sw; - NMDevice *device; - NetObject *object; - - object = get_selected_object (panel); - if (object == NULL) - return; - device = net_device_get_nm_device (NET_DEVICE (object)); - - if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_WIFI) - return; - - enabled = nm_client_wireless_get_enabled (client); - sw = GTK_SWITCH (gtk_builder_get_object (panel->priv->builder, - "device_wireless_off_switch")); - - panel->priv->updating_device = TRUE; - gtk_switch_set_active (sw, enabled); - panel->priv->updating_device = FALSE; -} - -static void -wimax_enabled_toggled (NMClient *client, - GParamSpec *pspec, - CcNetworkPanel *panel) -{ - gboolean enabled; - GtkSwitch *sw; - NMDevice *device; - NetObject *object; - - object = get_selected_object (panel); - if (object == NULL) - return; - device = net_device_get_nm_device (NET_DEVICE (object)); - - if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_WIMAX) - return; - - enabled = nm_client_wimax_get_enabled (client); - sw = GTK_SWITCH (gtk_builder_get_object (panel->priv->builder, - "device_wimax_off_switch")); - - panel->priv->updating_device = TRUE; - gtk_switch_set_active (sw, enabled); - panel->priv->updating_device = FALSE; -} - -static gboolean -device_is_hotspot (CcNetworkPanel *panel, - NMDevice *device) -{ - NMConnection *c; - NMSettingIP4Config *s_ip4; - - if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_WIFI) { - return FALSE; - } - - c = find_connection_for_device (panel, device); - if (c == NULL) { - return FALSE; - } - - s_ip4 = nm_connection_get_setting_ip4_config (c); - if (g_strcmp0 (nm_setting_ip4_config_get_method (s_ip4), - NM_SETTING_IP4_CONFIG_METHOD_SHARED) != 0) { - return FALSE; - } - - return TRUE; -} - -static const GByteArray * -device_get_hotspot_ssid (CcNetworkPanel *panel, - NMDevice *device) -{ - NMConnection *c; - NMSettingWireless *sw; - - c = find_connection_for_device (panel, device); - if (c == NULL) { - return FALSE; - } - - sw = nm_connection_get_setting_wireless (c); - return nm_setting_wireless_get_ssid (sw); -} - -static void -get_secrets_cb (NMRemoteConnection *c, - GHashTable *secrets, - GError *error, - gpointer data) -{ - CcNetworkPanel *panel = data; - NMSettingWireless *sw; - - sw = nm_connection_get_setting_wireless (NM_CONNECTION (c)); - - nm_connection_update_secrets (NM_CONNECTION (c), - nm_setting_wireless_get_security (sw), - secrets, NULL); - - refresh_ui (panel); -} - -static void -device_get_hotspot_security_details (CcNetworkPanel *panel, - NMDevice *device, - gchar **secret, - gchar **security) -{ - NMConnection *c; - NMSettingWireless *sw; - NMSettingWirelessSecurity *sws; - const gchar *key_mgmt; - const gchar *tmp_secret; - const gchar *tmp_security; - - c = find_connection_for_device (panel, device); - if (c == NULL) { - return; - } - - sw = nm_connection_get_setting_wireless (c); - sws = nm_connection_get_setting_wireless_security (c); - if (sw == NULL || sws == NULL) { - return; - } - - tmp_secret = NULL; - tmp_security = _("None"); - - key_mgmt = nm_setting_wireless_security_get_key_mgmt (sws); - if (strcmp (key_mgmt, "none") == 0) { - tmp_secret = nm_setting_wireless_security_get_wep_key (sws, 0); - tmp_security = _("WEP"); - } - else if (strcmp (key_mgmt, "wpa-none") == 0) { - tmp_secret = nm_setting_wireless_security_get_psk (sws); - tmp_security = _("WPA"); - } else { - g_warning ("unhandled security key-mgmt: %s", key_mgmt); - } - - /* If we don't have secrets, request them from NM and bail. - * We'll refresh the UI when secrets arrive. - */ - if (tmp_secret == NULL) { - nm_remote_connection_get_secrets ((NMRemoteConnection*)c, - nm_setting_wireless_get_security (sw), - get_secrets_cb, - panel); - return; - } - - if (secret) { - *secret = g_strdup (tmp_secret); - } - - if (security) { - *security = g_strdup (tmp_security); - } -} - -static void -refresh_header_ui (CcNetworkPanel *panel, NMDevice *device, const char *page_name) -{ - GtkWidget *widget; - char *wid_name; - GString *str; - NMDeviceState state; - NMDeviceType type; - gboolean is_hotspot; - gboolean is_connected; - guint speed = 0; - - type = nm_device_get_device_type (device); - state = nm_device_get_state (device); - is_hotspot = device_is_hotspot (panel, device); - - /* set header icon */ - wid_name = g_strdup_printf ("image_%s_device", page_name); - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, wid_name)); - g_free (wid_name); - gtk_image_set_from_icon_name (GTK_IMAGE (widget), - panel_device_to_icon_name (device), - GTK_ICON_SIZE_DIALOG); - - /* set device kind */ - wid_name = g_strdup_printf ("label_%s_device", page_name); - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, wid_name)); - g_free (wid_name); - gtk_label_set_label (GTK_LABEL (widget), - panel_device_to_localized_string (device)); - - /* set up the device on/off switch */ - wid_name = g_strdup_printf ("device_%s_off_switch", page_name); - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, wid_name)); - g_free (wid_name); - - /* keep this in sync with the signal handler setup in cc_network_panel_init */ - switch (type) { - case NM_DEVICE_TYPE_ETHERNET: - break; - case NM_DEVICE_TYPE_WIFI: - gtk_widget_show (widget); - wireless_enabled_toggled (panel->priv->client, NULL, panel); - if (state != NM_DEVICE_STATE_UNAVAILABLE) - speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (device)); - speed /= 1000; - break; - case NM_DEVICE_TYPE_WIMAX: - gtk_widget_show (widget); - wimax_enabled_toggled (panel->priv->client, NULL, panel); - break; - case NM_DEVICE_TYPE_MODEM: - break; - default: - gtk_widget_hide (widget); - break; - } - - /* set device state, with status and optionally speed */ - wid_name = g_strdup_printf ("label_%s_status", page_name); - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, wid_name)); - g_free (wid_name); - if (is_hotspot) { - str = g_string_new (_("Hotspot")); - } else { - str = g_string_new (panel_device_state_to_localized_string (device)); - } - if (speed > 0) { - g_string_append (str, " - "); - /* Translators: network device speed */ - g_string_append_printf (str, _("%d Mb/s"), speed); - } - gtk_label_set_label (GTK_LABEL (widget), str->str); - gtk_widget_set_tooltip_text (widget, panel_device_state_reason_to_localized_string (device)); - - /* The options button is always enabled for wired connections, - * and is sensitive for other connection types if the device - * is currently connected */ - wid_name = g_strdup_printf ("button_%s_options", page_name); - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, wid_name)); - g_free (wid_name); - if (widget != NULL) { - switch (type) { - default: - is_connected = find_connection_for_device (panel, device) != NULL; - gtk_widget_set_sensitive (widget, is_connected); - break; - } - } - g_string_free (str, TRUE); -} - -static void -device_refresh_wifi_ui (CcNetworkPanel *panel, NetDevice *device) -{ - GtkWidget *widget; - GtkWidget *sw; - const GPtrArray *aps; - GPtrArray *aps_unique = NULL; - GtkWidget *heading; - NMDeviceState state; - NMAccessPoint *ap; - NMAccessPoint *active_ap; - const char *str; - gchar *str_tmp; - GtkListStore *liststore_wireless_network; - guint i; - NMDevice *nm_device; - NMClientPermissionResult perm; - gboolean is_hotspot; - gchar *hotspot_ssid; - gchar *hotspot_secret; - gchar *hotspot_security; - gboolean can_start_hotspot; - - nm_device = net_device_get_nm_device (device); - state = nm_device_get_state (nm_device); - - refresh_header_ui (panel, nm_device, "wireless"); - - /* sort out hotspot ui */ - is_hotspot = device_is_hotspot (panel, nm_device); - hotspot_ssid = NULL; - hotspot_secret = NULL; - hotspot_security = NULL; - if (is_hotspot) { - const GByteArray *ssid; - ssid = device_get_hotspot_ssid (panel, nm_device); - if (ssid) { - hotspot_ssid = nm_utils_ssid_to_utf8 (ssid); - } - device_get_hotspot_security_details (panel, nm_device, &hotspot_secret, &hotspot_security); - } - - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, - "start_hotspot_button")); - gtk_widget_set_visible (widget, !is_hotspot); - - sw = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, - "device_wireless_off_switch")); - perm = nm_client_get_permission_result (panel->priv->client, NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN); - can_start_hotspot = gtk_switch_get_active (GTK_SWITCH (sw)) && - (perm == NM_CLIENT_PERMISSION_RESULT_YES || - perm == NM_CLIENT_PERMISSION_RESULT_AUTH); - gtk_widget_set_sensitive (widget, can_start_hotspot); - - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, - "stop_hotspot_button")); - gtk_widget_set_visible (widget, is_hotspot); - - panel_set_widget_data (panel, "hotspot", "network_name", hotspot_ssid); - g_free (hotspot_ssid); - - panel_set_widget_data (panel, "hotspot", "security_key", hotspot_secret); - g_free (hotspot_secret); - - /* device MAC */ - str = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (nm_device)); - panel_set_widget_data (panel, - "wireless", - "mac", - str); - /* security */ - active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (nm_device)); - if (state == NM_DEVICE_STATE_UNAVAILABLE) - str_tmp = NULL; - else if (is_hotspot) - str_tmp = hotspot_security; - else if (active_ap != NULL) - str_tmp = get_ap_security_string (active_ap); - else - str_tmp = g_strdup (""); - panel_set_widget_data (panel, - "wireless", - "security", - str_tmp); - g_free (str_tmp); - - heading = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, - "heading_wireless_network_name")); - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, - "combobox_wireless_network_name")); - /* populate access point dropdown */ - if (is_hotspot || state == NM_DEVICE_STATE_UNAVAILABLE) { - gtk_widget_hide (heading); - gtk_widget_hide (widget); - } else { - gtk_widget_show (heading); - gtk_widget_show (widget); - liststore_wireless_network = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder, - "liststore_wireless_network")); - panel->priv->updating_device = TRUE; - gtk_list_store_clear (liststore_wireless_network); - aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (nm_device)); - aps_unique = panel_get_strongest_unique_aps (aps); - - for (i = 0; i < aps_unique->len; i++) { - ap = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, i)); - add_access_point (panel, ap, active_ap, nm_device); - } - add_access_point_other (panel); - if (active_ap == NULL) { - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, - "combobox_wireless_network_name")); - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (widget), NULL); - gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (widget))), ""); - } - - panel->priv->updating_device = FALSE; - - g_ptr_array_unref (aps_unique); - } - - /* setup wireless button */ - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, - "button_wireless_button")); - gtk_widget_set_visible (widget, active_ap != NULL); -} - -static void -device_refresh_wimax_ui (CcNetworkPanel *panel, NetDevice *device) -{ - NMDevice *nm_device; - - nm_device = net_device_get_nm_device (device); - refresh_header_ui (panel, nm_device, "wimax"); -} - -static void -nm_device_refresh_device_ui (CcNetworkPanel *panel, NetDevice *device) -{ - CcNetworkPanelPrivate *priv = panel->priv; - const gchar *sub_pane = NULL; - gchar *str_tmp; - GtkWidget *widget; - NMDeviceType type; - NMIP4Config *ip4_config = NULL; - NMIP6Config *ip6_config = NULL; - NMDevice *nm_device; - gboolean has_ip4; - gboolean has_ip6; - gboolean is_hotspot; - - /* we have a new device */ - nm_device = net_device_get_nm_device (device); - type = nm_device_get_device_type (nm_device); - is_hotspot = device_is_hotspot (panel, nm_device); - g_debug ("device %s type %i (is-hotspot: %i)", - nm_device_get_udi (nm_device), type, is_hotspot); - - widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "notebook_types")); - - switch (type) { - case NM_DEVICE_TYPE_ETHERNET: - break; - case NM_DEVICE_TYPE_WIFI: - gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 0); - sub_pane = "wireless"; - device_refresh_wifi_ui (panel, device); - break; - case NM_DEVICE_TYPE_WIMAX: - device_refresh_wimax_ui (panel, device); - break; - case NM_DEVICE_TYPE_MODEM: - break; - default: - g_assert_not_reached (); - break; - } - - if (sub_pane == NULL) - goto out; - - /* get IP4 parameters */ - ip4_config = nm_device_get_ip4_config (nm_device); - if (!is_hotspot && ip4_config != NULL) { - /* IPv4 address */ - - str_tmp = get_ipv4_config_address_as_string (ip4_config, "address"); - panel_set_widget_data (panel, - sub_pane, - "ipv4", - str_tmp); - has_ip4 = str_tmp != NULL; - g_free (str_tmp); - - /* IPv4 DNS */ - str_tmp = get_ipv4_config_name_servers_as_string (ip4_config); - panel_set_widget_data (panel, - sub_pane, - "dns", - str_tmp); - g_free (str_tmp); - - /* IPv4 route */ - str_tmp = get_ipv4_config_address_as_string (ip4_config, "gateway"); - panel_set_widget_data (panel, - sub_pane, - "route", - str_tmp); - g_free (str_tmp); - - /* IPv4 netmask */ - if (type == NM_DEVICE_TYPE_ETHERNET) { - str_tmp = get_ipv4_config_address_as_string (ip4_config, "netmask"); - panel_set_widget_data (panel, - sub_pane, - "subnet", - str_tmp); - g_free (str_tmp); - } - } else { - /* IPv4 address */ - panel_set_widget_data (panel, - sub_pane, - "ipv4", - NULL); - has_ip4 = FALSE; - - /* IPv4 DNS */ - panel_set_widget_data (panel, - sub_pane, - "dns", - NULL); - - /* IPv4 route */ - panel_set_widget_data (panel, - sub_pane, - "route", - NULL); - - /* IPv4 netmask */ - if (type == NM_DEVICE_TYPE_ETHERNET) { - panel_set_widget_data (panel, - sub_pane, - "subnet", - NULL); - } - } - - /* get IP6 parameters */ - ip6_config = nm_device_get_ip6_config (nm_device); - if (!is_hotspot && ip6_config != NULL) { - - /* IPv6 address */ - str_tmp = get_ipv6_config_address_as_string (ip6_config); - panel_set_widget_data (panel, sub_pane, "ipv6", str_tmp); - has_ip6 = str_tmp != NULL; - g_free (str_tmp); - } else { - panel_set_widget_data (panel, sub_pane, "ipv6", NULL); - has_ip6 = FALSE; - } - - if (has_ip4 && has_ip6) { - panel_set_widget_heading (panel, sub_pane, "ipv4", _("IPv4 Address")); - panel_set_widget_heading (panel, sub_pane, "ipv6", _("IPv6 Address")); - } - else if (has_ip4) { - panel_set_widget_heading (panel, sub_pane, "ipv4", _("IP Address")); - } - else if (has_ip6) { - panel_set_widget_heading (panel, sub_pane, "ipv6", _("IP Address")); - } -out: ; -} - static gboolean panel_set_notebook_page_for_object (CcNetworkPanel *panel, NetObject *object) { @@ -1630,17 +643,12 @@ refresh_ui_idle (gpointer data) /* do we have a new-style NetObject-style panel widget */ ret = panel_set_notebook_page_for_object (panel, object); - - /* device */ if (!ret && NET_IS_DEVICE (object)) { /* we're not yet able to remove the connection */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "remove_toolbutton")); gtk_widget_set_sensitive (widget, FALSE); - - /* refresh device */ - nm_device_refresh_device_ui (panel, NET_DEVICE (object)); } out: priv->refresh_idle = 0; @@ -1989,42 +997,6 @@ panel_check_network_manager_version (CcNetworkPanel *panel) return ret; } -static void -edit_connection (GtkButton *button, CcNetworkPanel *panel) -{ - NMConnection *c; - const gchar *uuid; - gchar *cmdline; - GError *error; - NetObject *object; - NMDevice *device; - - object = get_selected_object (panel); - if (object == NULL) - return; - else { - device = net_device_get_nm_device (NET_DEVICE (object)); - c = find_connection_for_device (panel, device); - if (c == NULL) { - g_warning ("failed to find connection for device"); - return; - } - } - - uuid = nm_connection_get_uuid (c); - - cmdline = g_strdup_printf ("nm-connection-editor --edit %s", uuid); - g_debug ("Launching '%s'\n", cmdline); - - error = NULL; - if (!g_spawn_command_line_async (cmdline, &error)) { - g_warning ("Failed to launch nm-connection-editor: %s", error->message); - g_error_free (error); - } - - g_free (cmdline); -} - static void add_connection_cb (GtkToolButton *button, CcNetworkPanel *panel) { @@ -2067,98 +1039,6 @@ add_connection_cb (GtkToolButton *button, CcNetworkPanel *panel) } } -static void -forget_network_connection_delete_cb (NMRemoteConnection *connection, - GError *error, - gpointer user_data) -{ - if (error == NULL) - return; - g_warning ("failed to delete connection %s: %s", - nm_object_get_path (NM_OBJECT (connection)), - error->message); -} - -static void -forget_network_response_cb (GtkWidget *dialog, - gint response, - CcNetworkPanel *panel) -{ - NetObject *object; - NMDevice *device; - NMRemoteConnection *remote_connection; - - if (response != GTK_RESPONSE_OK) - goto out; - - /* get current device */ - object = get_selected_object (panel); - if (object == NULL) - return; - device = net_device_get_nm_device (NET_DEVICE (object)); - if (device == NULL) - goto out; - - /* delete the connection */ - remote_connection = NM_REMOTE_CONNECTION (find_connection_for_device (panel, device)); - if (remote_connection == NULL) { - g_warning ("failed to get remote connection"); - goto out; - } - nm_remote_connection_delete (remote_connection, - forget_network_connection_delete_cb, - panel); -out: - gtk_widget_destroy (dialog); -} - -static void -wireless_button_clicked_cb (GtkButton *button, CcNetworkPanel *panel) -{ - gboolean ret; - gchar *ssid_pretty = NULL; - gchar *ssid_target = NULL; - gchar *warning = NULL; - GtkComboBox *combobox; - GtkTreeIter iter; - GtkTreeModel *model; - GtkWidget *dialog; - GtkWidget *window; - - combobox = GTK_COMBO_BOX (gtk_builder_get_object (panel->priv->builder, - "combobox_wireless_network_name")); - ret = gtk_combo_box_get_active_iter (combobox, &iter); - if (!ret) - goto out; - - /* get entry */ - model = gtk_combo_box_get_model (GTK_COMBO_BOX (combobox)); - gtk_tree_model_get (model, &iter, - PANEL_WIRELESS_COLUMN_TITLE, &ssid_target, - -1); - - ssid_pretty = g_strdup_printf ("%s", ssid_target); - warning = g_strdup_printf (_("Network details for %s including password and any custom configuration will be lost"), ssid_pretty); - window = gtk_widget_get_toplevel (GTK_WIDGET (panel)); - dialog = gtk_message_dialog_new (GTK_WINDOW (window), - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_OTHER, - GTK_BUTTONS_NONE, - NULL); - gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), warning); - gtk_dialog_add_buttons (GTK_DIALOG (dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - _("Forget"), GTK_RESPONSE_OK, - NULL); - g_signal_connect (dialog, "response", - G_CALLBACK (forget_network_response_cb), panel); - gtk_window_present (GTK_WINDOW (dialog)); -out: - g_free (ssid_target); - g_free (ssid_pretty); - g_free (warning); -} - static void remove_connection (GtkToolButton *button, CcNetworkPanel *panel) { @@ -2190,588 +1070,6 @@ on_toplevel_map (GtkWidget *widget, } } -static void -connection_activate_cb (NMClient *client, - NMActiveConnection *connection, - GError *error, - gpointer user_data) -{ - CcNetworkPanel *panel = user_data; - - if (connection == NULL) { - /* failed to activate */ - refresh_ui (panel); - } -} - -static void -connection_add_activate_cb (NMClient *client, - NMActiveConnection *connection, - const char *path, - GError *error, - gpointer user_data) -{ - connection_activate_cb (client, connection, error, user_data); -} - -static void -connect_to_hidden_network (CcNetworkPanel *panel) -{ - CcNetworkPanelPrivate *priv = panel->priv; - - cc_network_panel_connect_to_hidden_network (panel, priv->client, priv->remote_settings); -} - -static void -wireless_ap_changed_cb (GtkComboBox *combo_box, CcNetworkPanel *panel) -{ - const GByteArray *ssid; - const gchar *ssid_tmp; - gboolean ret; - gchar *object_path = NULL; - gchar *ssid_target = NULL; - GSList *list, *l; - GSList *filtered; - GtkTreeIter iter; - GtkTreeModel *model; - NetObject *object; - NMConnection *connection; - NMConnection *connection_activate = NULL; - NMDevice *device; - NMSettingWireless *setting_wireless; - - if (panel->priv->updating_device) - goto out; - - ret = gtk_combo_box_get_active_iter (combo_box, &iter); - if (!ret) - goto out; - - object = get_selected_object (panel); - if (object == NULL) - goto out; - - device = net_device_get_nm_device (NET_DEVICE (object)); - if (device == NULL) - goto out; - - /* get entry */ - model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); - gtk_tree_model_get (model, &iter, - PANEL_WIRELESS_COLUMN_ID, &object_path, - PANEL_WIRELESS_COLUMN_TITLE, &ssid_target, - -1); - g_debug ("try to connect to WIFI network %s [%s]", - ssid_target, object_path); - if (g_strcmp0 (object_path, "ap-other...") == 0) { - connect_to_hidden_network (panel); - goto out; - } - - /* look for an existing connection we can use */ - list = nm_remote_settings_list_connections (panel->priv->remote_settings); - g_debug ("%i existing remote connections available", - g_slist_length (list)); - filtered = nm_device_filter_connections (device, list); - g_debug ("%i suitable remote connections to check", - g_slist_length (filtered)); - for (l = filtered; l; l = g_slist_next (l)) { - connection = NM_CONNECTION (l->data); - setting_wireless = nm_connection_get_setting_wireless (connection); - if (!NM_IS_SETTING_WIRELESS (setting_wireless)) - continue; - ssid = nm_setting_wireless_get_ssid (setting_wireless); - if (ssid == NULL) - continue; - ssid_tmp = nm_utils_escape_ssid (ssid->data, ssid->len); - if (g_strcmp0 (ssid_target, ssid_tmp) == 0) { - g_debug ("we found an existing connection %s to activate!", - nm_connection_get_id (connection)); - connection_activate = connection; - break; - } - } - - g_slist_free (list); - g_slist_free (filtered); - - /* activate the connection */ - if (connection_activate != NULL) { - nm_client_activate_connection (panel->priv->client, - connection_activate, - device, NULL, - connection_activate_cb, panel); - goto out; - } - - /* create one, as it's missing */ - g_debug ("no existing connection found for %s, creating", - ssid_target); - nm_client_add_and_activate_connection (panel->priv->client, - NULL, - device, object_path, - connection_add_activate_cb, panel); -out: - g_free (ssid_target); - g_free (object_path); -} - -static gint -wireless_ap_model_sort_cb (GtkTreeModel *model, - GtkTreeIter *a, - GtkTreeIter *b, - gpointer user_data) -{ - gchar *str_a; - gchar *str_b; - gint strength_a; - gint strength_b; - gboolean active_a; - gboolean active_b; - gint retval; - - gtk_tree_model_get (model, a, - PANEL_WIRELESS_COLUMN_SORT, &str_a, - PANEL_WIRELESS_COLUMN_STRENGTH, &strength_a, - PANEL_WIRELESS_COLUMN_ACTIVE, &active_a, - -1); - gtk_tree_model_get (model, b, - PANEL_WIRELESS_COLUMN_SORT, &str_b, - PANEL_WIRELESS_COLUMN_STRENGTH, &strength_b, - PANEL_WIRELESS_COLUMN_ACTIVE, &active_b, - -1); - - /* special case blank entries to the bottom */ - if (g_strcmp0 (str_a, "") == 0) { - retval = 1; - goto out; - } - if (g_strcmp0 (str_b, "") == 0) { - retval = -1; - goto out; - } - - if (active_a) { - retval = -1; - goto out; - } - - if (active_b) { - retval = 1; - goto out; - } - - /* case sensitive search like before */ - g_debug ("compare %s (%d) with %s (%d)", str_a, strength_a, str_b, strength_b); - retval = strength_b - strength_a; - -out: - g_free (str_a); - g_free (str_b); - - return retval; -} - -static GByteArray * -ssid_to_byte_array (const gchar *ssid) -{ - guint32 len; - GByteArray *ba; - - len = strlen (ssid); - ba = g_byte_array_sized_new (len); - g_byte_array_append (ba, (guchar *)ssid, len); - - return ba; -} - -static void -activate_cb (NMClient *client, - NMActiveConnection *connection, - GError *error, - CcNetworkPanel *panel) -{ - if (error) { - g_warning ("Failed to add new connection: (%d) %s", - error->code, - error->message); - return; - } - - refresh_ui (panel); -} - -static void -activate_new_cb (NMClient *client, - NMActiveConnection *connection, - const gchar *path, - GError *error, - CcNetworkPanel *panel) -{ - activate_cb (client, connection, error, panel); -} - -static gchar * -get_hostname (void) -{ - GDBusConnection *bus; - GVariant *res; - GVariant *inner; - gchar *str; - GError *error; - - error = NULL; - bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); - if (error != NULL) { - g_warning ("Failed to get system bus connection: %s", error->message); - g_error_free (error); - - return NULL; - } - res = g_dbus_connection_call_sync (bus, - "org.freedesktop.hostname1", - "/org/freedesktop/hostname1", - "org.freedesktop.DBus.Properties", - "Get", - g_variant_new ("(ss)", - "org.freedesktop.hostname1", - "PrettyHostname"), - (GVariantType*)"(v)", - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - g_object_unref (bus); - - if (error != NULL) { - g_warning ("Getting pretty hostname failed: %s", error->message); - g_error_free (error); - } - - str = NULL; - - if (res != NULL) { - g_variant_get (res, "(v)", &inner); - str = g_variant_dup_string (inner, NULL); - g_variant_unref (res); - } - - if (str == NULL || *str == '\0') { - str = g_strdup (g_get_host_name ()); - } - - if (str == NULL || *str == '\0') { - str = g_strdup ("GNOME"); - } - - return str; -} - -static GByteArray * -generate_ssid_for_hotspot (CcNetworkPanel *panel) -{ - GByteArray *ssid_array; - gchar *ssid; - - ssid = get_hostname (); - ssid_array = ssid_to_byte_array (ssid); - g_free (ssid); - - return ssid_array; -} - -static gchar * -generate_wep_key (CcNetworkPanel *panel) -{ - gchar key[11]; - gint i; - const gchar *hexdigits = "0123456789abcdef"; - - /* generate a 10-digit hex WEP key */ - for (i = 0; i < 10; i++) { - gint digit; - digit = g_random_int_range (0, 16); - key[i] = hexdigits[digit]; - } - key[10] = 0; - - return g_strdup (key); -} - -static gboolean -is_hotspot_connection (NMConnection *connection) -{ - NMSettingConnection *sc; - NMSettingWireless *sw; - NMSettingIP4Config *sip; - - sc = nm_connection_get_setting_connection (connection); - if (g_strcmp0 (nm_setting_connection_get_connection_type (sc), "802-11-wireless") != 0) { - return FALSE; - } - sw = nm_connection_get_setting_wireless (connection); - if (g_strcmp0 (nm_setting_wireless_get_mode (sw), "adhoc") != 0) { - return FALSE; - } - if (g_strcmp0 (nm_setting_wireless_get_security (sw), "802-11-wireless-security") != 0) { - return FALSE; - } - sip = nm_connection_get_setting_ip4_config (connection); - if (g_strcmp0 (nm_setting_ip4_config_get_method (sip), "shared") != 0) { - return FALSE; - } - - return TRUE; -} - -static void -start_shared_connection (CcNetworkPanel *panel) -{ - NMConnection *c; - NMConnection *tmp; - NMSettingConnection *sc; - NMSettingWireless *sw; - NMSettingIP4Config *sip; - NMSettingWirelessSecurity *sws; - NMDevice *device; - NetObject *object; - GByteArray *ssid_array; - gchar *wep_key; - const gchar *str_mac; - struct ether_addr *bin_mac; - GSList *connections; - GSList *filtered; - GSList *l; - - object = get_selected_object (panel); - device = net_device_get_nm_device (NET_DEVICE (object)); - g_assert (nm_device_get_device_type (device) == NM_DEVICE_TYPE_WIFI); - - connections = nm_remote_settings_list_connections (panel->priv->remote_settings); - filtered = nm_device_filter_connections (device, connections); - g_slist_free (connections); - c = NULL; - for (l = filtered; l; l = l->next) { - tmp = l->data; - if (is_hotspot_connection (tmp)) { - c = tmp; - break; - } - } - g_slist_free (filtered); - - if (c != NULL) { - g_debug ("activate existing hotspot connection\n"); - nm_client_activate_connection (panel->priv->client, - c, - device, - NULL, - (NMClientActivateFn)activate_cb, - panel); - return; - } - - g_debug ("create new hotspot connection\n"); - c = nm_connection_new (); - - sc = (NMSettingConnection *)nm_setting_connection_new (); - g_object_set (sc, - "type", "802-11-wireless", - "id", "Hotspot", - "autoconnect", FALSE, - NULL); - nm_connection_add_setting (c, (NMSetting *)sc); - - sw = (NMSettingWireless *)nm_setting_wireless_new (); - g_object_set (sw, - "mode", "adhoc", - "security", "802-11-wireless-security", - NULL); - - str_mac = nm_device_wifi_get_permanent_hw_address (NM_DEVICE_WIFI (device)); - bin_mac = ether_aton (str_mac); - if (bin_mac) { - GByteArray *hw_address; - - hw_address = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (hw_address, bin_mac->ether_addr_octet, ETH_ALEN); - g_object_set (sw, - "mac-address", hw_address, - NULL); - g_byte_array_unref (hw_address); - } - nm_connection_add_setting (c, (NMSetting *)sw); - - sip = (NMSettingIP4Config*) nm_setting_ip4_config_new (); - g_object_set (sip, "method", "shared", NULL); - nm_connection_add_setting (c, (NMSetting *)sip); - - ssid_array = generate_ssid_for_hotspot (panel); - g_object_set (sw, - "ssid", ssid_array, - NULL); - g_byte_array_unref (ssid_array); - - sws = (NMSettingWirelessSecurity*) nm_setting_wireless_security_new (); - wep_key = generate_wep_key (panel); - g_object_set (sws, - "key-mgmt", "none", - "wep-key0", wep_key, - "wep-key-type", NM_WEP_KEY_TYPE_KEY, - NULL); - g_free (wep_key); - nm_connection_add_setting (c, (NMSetting *)sws); - - nm_client_add_and_activate_connection (panel->priv->client, - c, - device, - NULL, - (NMClientAddActivateFn)activate_new_cb, - panel); - - g_object_unref (c); -} - -static void -start_hotspot_response_cb (GtkWidget *dialog, gint response, CcNetworkPanel *panel) -{ - if (response == GTK_RESPONSE_OK) { - start_shared_connection (panel); - } - gtk_widget_destroy (dialog); -} - -static void -start_hotspot (GtkButton *button, CcNetworkPanel *panel) -{ - NetObject *object; - NMDevice *device; - gboolean is_default; - const GPtrArray *connections; - const GPtrArray *devices; - NMActiveConnection *c; - NMAccessPoint *ap; - gchar *active_ssid; - gchar *warning; - gint i; - - warning = NULL; - - object = get_selected_object (panel); - device = net_device_get_nm_device (NET_DEVICE (object)); - connections = nm_client_get_active_connections (panel->priv->client); - if (connections == NULL || connections->len == 0) { - warning = g_strdup_printf ("%s\n\n%s", - _("Not connected to the internet."), - _("Create the hotspot anyway?")); - } else { - is_default = FALSE; - active_ssid = NULL; - for (i = 0; i < connections->len; i++) { - c = (NMActiveConnection *)connections->pdata[i]; - devices = nm_active_connection_get_devices (c); - if (devices && devices->pdata[0] == device) { - ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device)); - active_ssid = nm_utils_ssid_to_utf8 (nm_access_point_get_ssid (ap)); - is_default = nm_active_connection_get_default (c); - break; - } - } - - if (active_ssid != NULL) { - GString *str; - str = g_string_new (""); - g_string_append_printf (str, _("Disconnect from %s and create a new hotspot?"), active_ssid); - if (is_default) { - g_string_append (str, "\n\n"); - g_string_append (str, _("This is your only connection to the internet.")); - } - warning = g_string_free (str, FALSE); - } - } - - if (warning != NULL) { - GtkWidget *dialog; - GtkWidget *window; - - window = gtk_widget_get_toplevel (GTK_WIDGET (panel)); - dialog = gtk_message_dialog_new (GTK_WINDOW (window), - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_OTHER, - GTK_BUTTONS_NONE, - "%s", warning); - gtk_dialog_add_buttons (GTK_DIALOG (dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - _("Create _Hotspot"), GTK_RESPONSE_OK, - NULL); - g_signal_connect (dialog, "response", - G_CALLBACK (start_hotspot_response_cb), panel); - gtk_window_present (GTK_WINDOW (dialog)); - - return; - } - - /* if we get here, things look good to go ahead */ - start_shared_connection (panel); -} - -static void -stop_shared_connection (CcNetworkPanel *panel) -{ - const GPtrArray *connections; - const GPtrArray *devices; - NetObject *object; - NMDevice *device; - gint i; - NMActiveConnection *c; - - object = get_selected_object (panel); - device = net_device_get_nm_device (NET_DEVICE (object)); - - connections = nm_client_get_active_connections (panel->priv->client); - for (i = 0; i < connections->len; i++) { - c = (NMActiveConnection *)connections->pdata[i]; - - devices = nm_active_connection_get_devices (c); - if (devices && devices->pdata[0] == device) { - nm_client_deactivate_connection (panel->priv->client, c); - break; - } - } - - refresh_ui (panel); -} - -static void -stop_hotspot_response_cb (GtkWidget *dialog, gint response, CcNetworkPanel *panel) -{ - if (response == GTK_RESPONSE_OK) { - stop_shared_connection (panel); - } - gtk_widget_destroy (dialog); -} - -static void -stop_hotspot (GtkButton *button, CcNetworkPanel *panel) -{ - GtkWidget *dialog; - GtkWidget *window; - - window = gtk_widget_get_toplevel (GTK_WIDGET (panel)); - dialog = gtk_message_dialog_new (GTK_WINDOW (window), - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_OTHER, - GTK_BUTTONS_NONE, - _("Stop hotspot and disconnect any users?")); - gtk_dialog_add_buttons (GTK_DIALOG (dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - _("_Stop Hotspot"), GTK_RESPONSE_OK, - NULL); - g_signal_connect (dialog, "response", - G_CALLBACK (stop_hotspot_response_cb), panel); - gtk_window_present (GTK_WINDOW (dialog)); -} - static gboolean network_add_shell_header_widgets_cb (gpointer user_data) { @@ -2809,11 +1107,8 @@ cc_network_panel_init (CcNetworkPanel *panel) { DBusGConnection *bus = NULL; GError *error = NULL; - GtkCellRenderer *renderer; - GtkComboBox *combobox; GtkStyleContext *context; GtkTreeSelection *selection; - GtkTreeSortable *sortable; GtkWidget *widget; GtkWidget *toplevel; @@ -2852,52 +1147,6 @@ cc_network_panel_init (CcNetworkPanel *panel) /* add the virtual proxy device */ panel_add_proxy_device (panel); - /* setup wireless combobox model */ - combobox = GTK_COMBO_BOX (gtk_builder_get_object (panel->priv->builder, - "combobox_wireless_network_name")); - g_signal_connect (combobox, "changed", - G_CALLBACK (wireless_ap_changed_cb), - panel); - - /* sort networks in drop down */ - sortable = GTK_TREE_SORTABLE (gtk_builder_get_object (panel->priv->builder, - "liststore_wireless_network")); - gtk_tree_sortable_set_sort_column_id (sortable, - PANEL_WIRELESS_COLUMN_SORT, - GTK_SORT_ASCENDING); - gtk_tree_sortable_set_sort_func (sortable, - PANEL_WIRELESS_COLUMN_SORT, - wireless_ap_model_sort_cb, - panel, - NULL); - - renderer = panel_cell_renderer_mode_new (); - gtk_cell_renderer_set_padding (renderer, 4, 0); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox), - renderer, - FALSE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer, - "mode", PANEL_WIRELESS_COLUMN_MODE, - NULL); - - renderer = panel_cell_renderer_signal_new (); - gtk_cell_renderer_set_padding (renderer, 4, 0); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox), - renderer, - FALSE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer, - "signal", PANEL_WIRELESS_COLUMN_STRENGTH, - NULL); - - renderer = panel_cell_renderer_security_new (); - gtk_cell_renderer_set_padding (renderer, 4, 0); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox), - renderer, - FALSE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer, - "security", PANEL_WIRELESS_COLUMN_SECURITY, - NULL); - /* use NetworkManager client */ panel->priv->client = nm_client_new (); g_signal_connect (panel->priv->client, "notify::" NM_CLIENT_MANAGER_RUNNING, @@ -2909,30 +1158,6 @@ cc_network_panel_init (CcNetworkPanel *panel) g_signal_connect (panel->priv->client, "device-removed", G_CALLBACK (device_removed_cb), panel); - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, - "device_wireless_off_switch")); - g_signal_connect (widget, "notify::active", - G_CALLBACK (device_off_toggled), panel); - - g_signal_connect (panel->priv->client, "notify::wireless-enabled", - G_CALLBACK (wireless_enabled_toggled), panel); - g_signal_connect (panel->priv->client, "notify::wimax-enabled", - G_CALLBACK (wimax_enabled_toggled), panel); - - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, - "start_hotspot_button")); - g_signal_connect (widget, "clicked", - G_CALLBACK (start_hotspot), panel); - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, - "stop_hotspot_button")); - g_signal_connect (widget, "clicked", - G_CALLBACK (stop_hotspot), panel); - - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, - "button_wireless_options")); - g_signal_connect (widget, "clicked", - G_CALLBACK (edit_connection), panel); - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "add_toolbutton")); g_signal_connect (widget, "clicked", @@ -2944,12 +1169,6 @@ cc_network_panel_init (CcNetworkPanel *panel) g_signal_connect (widget, "clicked", G_CALLBACK (remove_connection), panel); - /* setup wireless button */ - widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, - "button_wireless_button")); - g_signal_connect (widget, "clicked", - G_CALLBACK (wireless_button_clicked_cb), panel); - /* add remote settings such as VPN settings as virtual devices */ bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); if (bus == NULL) { diff --git a/panels/network/net-device-wifi.c b/panels/network/net-device-wifi.c new file mode 100644 index 000000000..f01c93d1e --- /dev/null +++ b/panels/network/net-device-wifi.c @@ -0,0 +1,1538 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2011-2012 Richard Hughes + * + * Licensed under the GNU General Public License Version 2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include + +//#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "network-dialogs.h" +#include "panel-common.h" +#include "panel-cell-renderer-mode.h" +#include "panel-cell-renderer-signal.h" +#include "panel-cell-renderer-security.h" + +#include "net-device-wifi.h" + +#define NET_DEVICE_WIFI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_DEVICE_WIFI, NetDeviceWifiPrivate)) + +static void nm_device_wifi_refresh_ui (NetDeviceWifi *device_wifi); + +struct _NetDeviceWifiPrivate +{ + GtkBuilder *builder; + gboolean updating_device; +}; + +G_DEFINE_TYPE (NetDeviceWifi, net_device_wifi, NET_TYPE_DEVICE) + +enum { + COLUMN_ID, + COLUMN_TITLE, + COLUMN_SORT, + COLUMN_STRENGTH, + COLUMN_MODE, + COLUMN_SECURITY, + COLUMN_ACTIVE, + COLUMN_LAST +}; + +static GtkWidget * +device_wifi_proxy_add_to_notebook (NetObject *object, + GtkNotebook *notebook, + GtkSizeGroup *heading_size_group) +{ + GtkWidget *widget; + GtkWindow *window; + NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (object); + + /* add widgets to size group */ + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "heading_ipv4")); + gtk_size_group_add_widget (heading_size_group, widget); + + /* reparent */ + window = GTK_WINDOW (gtk_builder_get_object (device_wifi->priv->builder, + "window_tmp")); + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "vbox5")); + g_object_ref (widget); + gtk_container_remove (GTK_CONTAINER (window), widget); + gtk_notebook_append_page (notebook, widget, NULL); + g_object_unref (widget); + return widget; +} + +static guint +get_access_point_security (NMAccessPoint *ap) +{ + NM80211ApFlags flags; + NM80211ApSecurityFlags wpa_flags; + NM80211ApSecurityFlags rsn_flags; + guint type; + + flags = nm_access_point_get_flags (ap); + wpa_flags = nm_access_point_get_wpa_flags (ap); + rsn_flags = nm_access_point_get_rsn_flags (ap); + + if (!(flags & NM_802_11_AP_FLAGS_PRIVACY) && + wpa_flags == NM_802_11_AP_SEC_NONE && + rsn_flags == NM_802_11_AP_SEC_NONE) + type = NM_AP_SEC_NONE; + else if ((flags & NM_802_11_AP_FLAGS_PRIVACY) && + wpa_flags == NM_802_11_AP_SEC_NONE && + rsn_flags == NM_802_11_AP_SEC_NONE) + type = NM_AP_SEC_WEP; + else if (!(flags & NM_802_11_AP_FLAGS_PRIVACY) && + wpa_flags != NM_802_11_AP_SEC_NONE && + rsn_flags != NM_802_11_AP_SEC_NONE) + type = NM_AP_SEC_WPA; + else + type = NM_AP_SEC_WPA2; + + return type; +} + +static void +add_access_point (NetDeviceWifi *device_wifi, NMAccessPoint *ap, NMAccessPoint *active, NMDevice *device) +{ + NetDeviceWifiPrivate *priv = device_wifi->priv; + const GByteArray *ssid; + const gchar *ssid_text; + const gchar *object_path; + GtkListStore *liststore_network; + GtkTreeIter treeiter; + GtkWidget *widget; + gboolean is_active_ap; + + ssid = nm_access_point_get_ssid (ap); + if (ssid == NULL) + return; + ssid_text = nm_utils_escape_ssid (ssid->data, ssid->len); + + is_active_ap = active && nm_utils_same_ssid (ssid, nm_access_point_get_ssid (active), TRUE); + + liststore_network = GTK_LIST_STORE (gtk_builder_get_object (priv->builder, + "liststore_network")); + + object_path = nm_object_get_path (NM_OBJECT (ap)); + gtk_list_store_insert_with_values (liststore_network, + &treeiter, + -1, + COLUMN_ID, object_path, + COLUMN_TITLE, ssid_text, + COLUMN_SORT, ssid_text, + COLUMN_STRENGTH, nm_access_point_get_strength (ap), + COLUMN_MODE, nm_access_point_get_mode (ap), + COLUMN_SECURITY, get_access_point_security (ap), + COLUMN_ACTIVE, is_active_ap, + -1); + + /* is this what we're on already? */ + if (is_active_ap) { + widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, + "combobox_network_name")); + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (widget), &treeiter); + } + +// if (priv->arg_operation == OPERATION_CONNECT_8021X && +// g_strcmp0(priv->arg_device, nm_object_get_path (NM_OBJECT (device))) == 0 && +// g_strcmp0(priv->arg_access_point, object_path) == 0) { +// cc_network_panel_connect_to_8021x_network (panel, +// priv->client, +// priv->remote_settings, +// device, +// ap); +// priv->arg_operation = OPERATION_NULL; /* done */ +// } +} + +static void +add_access_point_other (NetDeviceWifi *device_wifi) +{ + NetDeviceWifiPrivate *priv = device_wifi->priv; + GtkListStore *liststore_network; + GtkTreeIter treeiter; + + liststore_network = GTK_LIST_STORE (gtk_builder_get_object (priv->builder, + "liststore_network")); + + gtk_list_store_append (liststore_network, &treeiter); + gtk_list_store_set (liststore_network, + &treeiter, + COLUMN_ID, "ap-other...", + /* TRANSLATORS: this is when the access point is not listed + * in the dropdown (or hidden) and the user has to select + * another entry manually */ + COLUMN_TITLE, C_("Wireless access point", "Other..."), + /* always last */ + COLUMN_SORT, "", + COLUMN_STRENGTH, 0, + COLUMN_MODE, NM_802_11_MODE_UNKNOWN, + COLUMN_SECURITY, NM_AP_SEC_UNKNOWN, + -1); +} + +static GPtrArray * +panel_get_strongest_unique_aps (const GPtrArray *aps) +{ + const GByteArray *ssid; + const GByteArray *ssid_tmp; + GPtrArray *aps_unique = NULL; + gboolean add_ap; + guint i; + guint j; + NMAccessPoint *ap; + NMAccessPoint *ap_tmp; + + /* we will have multiple entries for typical hotspots, just + * filter to the one with the strongest signal */ + aps_unique = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); + if (aps != NULL) + for (i = 0; i < aps->len; i++) { + ap = NM_ACCESS_POINT (g_ptr_array_index (aps, i)); + + /* Hidden SSIDs don't get shown in the list */ + ssid = nm_access_point_get_ssid (ap); + if (!ssid) + continue; + + add_ap = TRUE; + + /* get already added list */ + for (j=0; jlen; j++) { + ap_tmp = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, j)); + ssid_tmp = nm_access_point_get_ssid (ap_tmp); + g_assert (ssid_tmp); + + /* is this the same type and data? */ + if (nm_utils_same_ssid (ssid, ssid_tmp, TRUE)) { + + g_debug ("found duplicate: %s", + nm_utils_escape_ssid (ssid_tmp->data, + ssid_tmp->len)); + + /* the new access point is stronger */ + if (nm_access_point_get_strength (ap) > + nm_access_point_get_strength (ap_tmp)) { + g_debug ("removing %s", + nm_utils_escape_ssid (ssid_tmp->data, + ssid_tmp->len)); + g_ptr_array_remove (aps_unique, ap_tmp); + add_ap = TRUE; + } else { + add_ap = FALSE; + } + + break; + } + } + if (add_ap) { + g_debug ("adding %s", + nm_utils_escape_ssid (ssid->data, + ssid->len)); + g_ptr_array_add (aps_unique, g_object_ref (ap)); + } + } + return aps_unique; +} + +static gchar * +get_ap_security_string (NMAccessPoint *ap) +{ + NM80211ApSecurityFlags wpa_flags, rsn_flags; + NM80211ApFlags flags; + GString *str; + + flags = nm_access_point_get_flags (ap); + wpa_flags = nm_access_point_get_wpa_flags (ap); + rsn_flags = nm_access_point_get_rsn_flags (ap); + + str = g_string_new (""); + if ((flags & NM_802_11_AP_FLAGS_PRIVACY) && + (wpa_flags == NM_802_11_AP_SEC_NONE) && + (rsn_flags == NM_802_11_AP_SEC_NONE)) { + /* TRANSLATORS: this WEP WiFi security */ + g_string_append_printf (str, "%s, ", _("WEP")); + } + if (wpa_flags != NM_802_11_AP_SEC_NONE) { + /* TRANSLATORS: this WPA WiFi security */ + g_string_append_printf (str, "%s, ", _("WPA")); + } + if (rsn_flags != NM_802_11_AP_SEC_NONE) { + /* TRANSLATORS: this WPA WiFi security */ + g_string_append_printf (str, "%s, ", _("WPA2")); + } + if ((wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) || + (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { + /* TRANSLATORS: this Enterprise WiFi security */ + g_string_append_printf (str, "%s, ", _("Enterprise")); + } + if (str->len > 0) + g_string_set_size (str, str->len - 2); + else { + /* TRANSLATORS: this no (!) WiFi security */ + g_string_append (str, _("None")); + } + return g_string_free (str, FALSE); +} + +static void +wireless_enabled_toggled (NMClient *client, + GParamSpec *pspec, + NetDeviceWifi *device_wifi) +{ + gboolean enabled; + GtkSwitch *sw; + NMDevice *device; + + device = net_device_get_nm_device (NET_DEVICE (device_wifi)); + if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_WIFI) + return; + + enabled = nm_client_wireless_get_enabled (client); + sw = GTK_SWITCH (gtk_builder_get_object (device_wifi->priv->builder, + "device_off_switch")); + + device_wifi->priv->updating_device = TRUE; + gtk_switch_set_active (sw, enabled); + device_wifi->priv->updating_device = FALSE; +} + +#if 0 +static void +update_off_switch_from_device_state (GtkSwitch *sw, + NMDeviceState state, + NetDeviceWifi *device_wifi) +{ + device_wifi->priv->updating_device = TRUE; + switch (state) { + case NM_DEVICE_STATE_UNMANAGED: + case NM_DEVICE_STATE_UNAVAILABLE: + case NM_DEVICE_STATE_DISCONNECTED: + case NM_DEVICE_STATE_DEACTIVATING: + case NM_DEVICE_STATE_FAILED: + gtk_switch_set_active (sw, FALSE); + break; + default: + gtk_switch_set_active (sw, TRUE); + break; + } + device_wifi->priv->updating_device = FALSE; +} +#endif + +static NMConnection * +find_connection_for_device (NetDeviceWifi *device_wifi, + NMDevice *device) +{ + NetDevice *tmp; + NMConnection *connection; + NMRemoteSettings *remote_settings; + NMClient *client; + + client = net_object_get_client (NET_OBJECT (device_wifi)); + remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi)); + tmp = g_object_new (NET_TYPE_DEVICE, + "client", client, + "remote-settings", remote_settings, + "nm-device", device, + NULL); + connection = net_device_get_find_connection (tmp); + g_object_unref (tmp); + return connection; +} + +static gboolean +device_is_hotspot (NetDeviceWifi *device_wifi) +{ + NMConnection *c; + NMSettingIP4Config *s_ip4; + NMDevice *device; + + device = net_device_get_nm_device (NET_DEVICE (device_wifi)); + if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_WIFI) { + return FALSE; + } + + c = find_connection_for_device (device_wifi, device); + if (c == NULL) { + return FALSE; + } + + s_ip4 = nm_connection_get_setting_ip4_config (c); + if (g_strcmp0 (nm_setting_ip4_config_get_method (s_ip4), + NM_SETTING_IP4_CONFIG_METHOD_SHARED) != 0) { + return FALSE; + } + + return TRUE; +} + +static const GByteArray * +device_get_hotspot_ssid (NetDeviceWifi *device_wifi, + NMDevice *device) +{ + NMConnection *c; + NMSettingWireless *sw; + + c = find_connection_for_device (device_wifi, device); + if (c == NULL) { + return FALSE; + } + + sw = nm_connection_get_setting_wireless (c); + return nm_setting_wireless_get_ssid (sw); +} + +static void +get_secrets_cb (NMRemoteConnection *c, + GHashTable *secrets, + GError *error, + gpointer data) +{ + NetDeviceWifi *device_wifi = data; + NMSettingWireless *sw; + + sw = nm_connection_get_setting_wireless (NM_CONNECTION (c)); + + nm_connection_update_secrets (NM_CONNECTION (c), + nm_setting_wireless_get_security (sw), + secrets, NULL); + + nm_device_wifi_refresh_ui (device_wifi); +} + +static void +device_get_hotspot_security_details (NetDeviceWifi *device_wifi, + NMDevice *device, + gchar **secret, + gchar **security) +{ + NMConnection *c; + NMSettingWireless *sw; + NMSettingWirelessSecurity *sws; + const gchar *key_mgmt; + const gchar *tmp_secret; + const gchar *tmp_security; + + c = find_connection_for_device (device_wifi, device); + if (c == NULL) { + return; + } + + sw = nm_connection_get_setting_wireless (c); + sws = nm_connection_get_setting_wireless_security (c); + if (sw == NULL || sws == NULL) { + return; + } + + tmp_secret = NULL; + tmp_security = _("None"); + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (sws); + if (strcmp (key_mgmt, "none") == 0) { + tmp_secret = nm_setting_wireless_security_get_wep_key (sws, 0); + tmp_security = _("WEP"); + } + else if (strcmp (key_mgmt, "wpa-none") == 0) { + tmp_secret = nm_setting_wireless_security_get_psk (sws); + tmp_security = _("WPA"); + } else { + g_warning ("unhandled security key-mgmt: %s", key_mgmt); + } + + /* If we don't have secrets, request them from NM and bail. + * We'll refresh the UI when secrets arrive. + */ + if (tmp_secret == NULL) { + nm_remote_connection_get_secrets ((NMRemoteConnection*)c, + nm_setting_wireless_get_security (sw), + get_secrets_cb, + device_wifi); + return; + } + + if (secret) { + *secret = g_strdup (tmp_secret); + } + + if (security) { + *security = g_strdup (tmp_security); + } +} + +static void +nm_device_wifi_refresh_ui (NetDeviceWifi *device_wifi) +{ + char *wid_name; + const char *str; + const GPtrArray *aps; + gboolean can_start_hotspot; + gboolean is_connected; + gboolean is_hotspot; + gchar *hotspot_secret; + gchar *hotspot_security; + gchar *hotspot_ssid; + gchar *str_tmp; + GPtrArray *aps_unique = NULL; + GString *string; + GtkListStore *liststore_network; + GtkWidget *heading; + GtkWidget *sw; + GtkWidget *widget; + guint i; + guint speed = 0; + NMAccessPoint *active_ap; + NMAccessPoint *ap; + NMClientPermissionResult perm; + NMDevice *nm_device; + NMDeviceState state; + NMDeviceType type; + NMClient *client; + NetDeviceWifiPrivate *priv = device_wifi->priv; + + nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi)); + type = nm_device_get_device_type (nm_device); + state = nm_device_get_state (nm_device); + is_hotspot = device_is_hotspot (device_wifi); + + /* set device kind */ + wid_name = g_strdup ("label_device"); + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, wid_name)); + g_free (wid_name); + gtk_label_set_label (GTK_LABEL (widget), + panel_device_to_localized_string (nm_device)); + + /* set up the device on/off switch */ + wid_name = g_strdup ("device_off_switch"); + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, wid_name)); + g_free (wid_name); + + /* keep this in sync with the signal handler setup in cc_network_panel_init */ + gtk_widget_show (widget); + client = net_object_get_client (NET_OBJECT (device_wifi)); + wireless_enabled_toggled (client, NULL, device_wifi); + if (state != NM_DEVICE_STATE_UNAVAILABLE) + speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (nm_device)); + speed /= 1000; + + /* set device state, with status and optionally speed */ + wid_name = g_strdup ("label_status"); + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, wid_name)); + g_free (wid_name); + if (is_hotspot) { + string = g_string_new (_("Hotspot")); + } else { + string = g_string_new (panel_device_state_to_localized_string (nm_device)); + } + if (speed > 0) { + g_string_append (string, " - "); + /* Translators: network device speed */ + g_string_append_printf (string, _("%d Mb/s"), speed); + } + gtk_label_set_label (GTK_LABEL (widget), string->str); + gtk_widget_set_tooltip_text (widget, panel_device_state_reason_to_localized_string (nm_device)); + + /* The options button is always enabled for wired connections, + * and is sensitive for other connection types if the device + * is currently connected */ + wid_name = g_strdup ("button_options"); + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, wid_name)); + g_free (wid_name); + if (widget != NULL) { + switch (type) { + default: + is_connected = find_connection_for_device (device_wifi, nm_device) != NULL; + gtk_widget_set_sensitive (widget, is_connected); + break; + } + } + g_string_free (string, TRUE); + + /* sort out hotspot ui */ + is_hotspot = device_is_hotspot (device_wifi); + hotspot_ssid = NULL; + hotspot_secret = NULL; + hotspot_security = NULL; + if (is_hotspot) { + const GByteArray *ssid; + ssid = device_get_hotspot_ssid (device_wifi, nm_device); + if (ssid) { + hotspot_ssid = nm_utils_ssid_to_utf8 (ssid); + } + device_get_hotspot_security_details (device_wifi, nm_device, &hotspot_secret, &hotspot_security); + } + + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "start_hotspot_button")); + gtk_widget_set_visible (widget, !is_hotspot); + + sw = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "device_off_switch")); + perm = nm_client_get_permission_result (client, NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN); + can_start_hotspot = gtk_switch_get_active (GTK_SWITCH (sw)) && + (perm == NM_CLIENT_PERMISSION_RESULT_YES || + perm == NM_CLIENT_PERMISSION_RESULT_AUTH); + gtk_widget_set_sensitive (widget, can_start_hotspot); + + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "stop_hotspot_button")); + gtk_widget_set_visible (widget, is_hotspot); + + panel_set_device_widget_details (device_wifi->priv->builder, + "hotspot_network_name", + hotspot_ssid); + g_free (hotspot_ssid); + + panel_set_device_widget_details (device_wifi->priv->builder, + "hotspot_security_key", + hotspot_secret); + g_free (hotspot_secret); + + /* device MAC */ + str = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (nm_device)); + panel_set_device_widget_details (device_wifi->priv->builder, + "mac", + str); + /* security */ + active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (nm_device)); + if (state == NM_DEVICE_STATE_UNAVAILABLE) + str_tmp = NULL; + else if (is_hotspot) + str_tmp = hotspot_security; + else if (active_ap != NULL) + str_tmp = get_ap_security_string (active_ap); + else + str_tmp = g_strdup (""); + panel_set_device_widget_details (device_wifi->priv->builder, + "security", + str_tmp); + g_free (str_tmp); + + heading = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "heading_network_name")); + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "combobox_network_name")); + /* populate access point dropdown */ + if (is_hotspot || state == NM_DEVICE_STATE_UNAVAILABLE) { + gtk_widget_hide (heading); + gtk_widget_hide (widget); + } else { + gtk_widget_show (heading); + gtk_widget_show (widget); + liststore_network = GTK_LIST_STORE (gtk_builder_get_object (device_wifi->priv->builder, + "liststore_network")); + device_wifi->priv->updating_device = TRUE; + gtk_list_store_clear (liststore_network); + aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (nm_device)); + aps_unique = panel_get_strongest_unique_aps (aps); + + for (i = 0; i < aps_unique->len; i++) { + ap = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, i)); + add_access_point (device_wifi, ap, active_ap, nm_device); + } + add_access_point_other (device_wifi); + if (active_ap == NULL) { + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "combobox_network_name")); + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (widget), NULL); + gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (widget))), ""); + } + + device_wifi->priv->updating_device = FALSE; + + g_ptr_array_unref (aps_unique); + } + + /* setup wireless button */ + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "button_forget")); + gtk_widget_set_visible (widget, active_ap != NULL); + + /* device MAC */ + str = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (nm_device)); + panel_set_device_widget_details (priv->builder, "mac", str); + + /* set IP entries */ + panel_set_device_widgets (priv->builder, nm_device); +} + +static void +device_wifi_refresh (NetObject *object) +{ + NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (object); + nm_device_wifi_refresh_ui (device_wifi); +} + +static void +device_off_toggled (GtkSwitch *sw, + GParamSpec *pspec, + NetDeviceWifi *device_wifi) +{ + NMClient *client; + gboolean active; + + if (device_wifi->priv->updating_device) + return; + + client = net_object_get_client (NET_OBJECT (device_wifi)); + active = gtk_switch_get_active (sw); + nm_client_wireless_set_enabled (client, active); +} + +static void +forget_network_connection_delete_cb (NMRemoteConnection *connection, + GError *error, + gpointer user_data) +{ + if (error == NULL) + return; + g_warning ("failed to delete connection %s: %s", + nm_object_get_path (NM_OBJECT (connection)), + error->message); +} + +static void +forget_network_response_cb (GtkWidget *dialog, + gint response, + NetDeviceWifi *device_wifi) +{ + NMDevice *device; + NMRemoteConnection *remote_connection; + + if (response != GTK_RESPONSE_OK) + goto out; + + device = net_device_get_nm_device (NET_DEVICE (device_wifi)); + if (device == NULL) + goto out; + + /* delete the connection */ + remote_connection = NM_REMOTE_CONNECTION (find_connection_for_device (device_wifi, device)); + if (remote_connection == NULL) { + g_warning ("failed to get remote connection"); + goto out; + } + nm_remote_connection_delete (remote_connection, + forget_network_connection_delete_cb, + device_wifi); +out: + gtk_widget_destroy (dialog); +} + +static void +forget_button_clicked_cb (GtkButton *button, NetDeviceWifi *device_wifi) +{ + gboolean ret; + gchar *ssid_pretty = NULL; + gchar *ssid_target = NULL; + gchar *warning = NULL; + GtkComboBox *combobox; + GtkTreeIter iter; + GtkTreeModel *model; + GtkWidget *dialog; + GtkWidget *window; + CcNetworkPanel *panel; + + combobox = GTK_COMBO_BOX (gtk_builder_get_object (device_wifi->priv->builder, + "combobox_network_name")); + ret = gtk_combo_box_get_active_iter (combobox, &iter); + if (!ret) + goto out; + + /* get entry */ + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combobox)); + gtk_tree_model_get (model, &iter, + COLUMN_TITLE, &ssid_target, + -1); + + ssid_pretty = g_strdup_printf ("%s", ssid_target); + warning = g_strdup_printf (_("Network details for %s including password and any custom configuration will be lost"), ssid_pretty); + panel = net_object_get_panel (NET_OBJECT (device_wifi)); + window = gtk_widget_get_toplevel (GTK_WIDGET (panel)); + dialog = gtk_message_dialog_new (GTK_WINDOW (window), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_OTHER, + GTK_BUTTONS_NONE, + NULL); + gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), warning); + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + _("Forget"), GTK_RESPONSE_OK, + NULL); + g_signal_connect (dialog, "response", + G_CALLBACK (forget_network_response_cb), device_wifi); + gtk_window_present (GTK_WINDOW (dialog)); +out: + g_free (ssid_target); + g_free (ssid_pretty); + g_free (warning); +} + + +static void +connect_to_hidden_network (NetDeviceWifi *device_wifi) +{ + NMRemoteSettings *remote_settings; + NMClient *client; + CcNetworkPanel *panel; + + remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi)); + client = net_object_get_client (NET_OBJECT (device_wifi)); + panel = net_object_get_panel (NET_OBJECT (device_wifi)); + cc_network_panel_connect_to_hidden_network (panel, client, remote_settings); +} + +static void +connection_add_activate_cb (NMClient *client, + NMActiveConnection *connection, + const char *path, + GError *error, + gpointer user_data) +{ + NetDeviceWifi *device_wifi = user_data; + + if (connection == NULL) { + /* failed to activate */ + nm_device_wifi_refresh_ui (device_wifi); + } +} + +static void +connection_activate_cb (NMClient *client, + NMActiveConnection *connection, + GError *error, + gpointer user_data) +{ + NetDeviceWifi *device_wifi = user_data; + + if (connection == NULL) { + /* failed to activate */ + nm_device_wifi_refresh_ui (device_wifi); + } +} + +static void +wireless_ap_changed_cb (GtkComboBox *combo_box, NetDeviceWifi *device_wifi) +{ + const GByteArray *ssid; + const gchar *ssid_tmp; + gboolean ret; + gchar *object_path = NULL; + gchar *ssid_target = NULL; + GSList *list, *l; + GSList *filtered; + GtkTreeIter iter; + GtkTreeModel *model; + NMConnection *connection; + NMConnection *connection_activate = NULL; + NMDevice *device; + NMSettingWireless *setting_wireless; + NMRemoteSettings *remote_settings; + NMClient *client; + + if (device_wifi->priv->updating_device) + goto out; + + ret = gtk_combo_box_get_active_iter (combo_box, &iter); + if (!ret) + goto out; + + device = net_device_get_nm_device (NET_DEVICE (device_wifi)); + if (device == NULL) + goto out; + + /* get entry */ + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); + gtk_tree_model_get (model, &iter, + COLUMN_ID, &object_path, + COLUMN_TITLE, &ssid_target, + -1); + g_debug ("try to connect to WIFI network %s [%s]", + ssid_target, object_path); + if (g_strcmp0 (object_path, "ap-other...") == 0) { + connect_to_hidden_network (device_wifi); + goto out; + } + + /* look for an existing connection we can use */ + remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi)); + list = nm_remote_settings_list_connections (remote_settings); + g_debug ("%i existing remote connections available", + g_slist_length (list)); + filtered = nm_device_filter_connections (device, list); + g_debug ("%i suitable remote connections to check", + g_slist_length (filtered)); + for (l = filtered; l; l = g_slist_next (l)) { + connection = NM_CONNECTION (l->data); + setting_wireless = nm_connection_get_setting_wireless (connection); + if (!NM_IS_SETTING_WIRELESS (setting_wireless)) + continue; + ssid = nm_setting_wireless_get_ssid (setting_wireless); + if (ssid == NULL) + continue; + ssid_tmp = nm_utils_escape_ssid (ssid->data, ssid->len); + if (g_strcmp0 (ssid_target, ssid_tmp) == 0) { + g_debug ("we found an existing connection %s to activate!", + nm_connection_get_id (connection)); + connection_activate = connection; + break; + } + } + + g_slist_free (list); + g_slist_free (filtered); + + /* activate the connection */ + client = net_object_get_client (NET_OBJECT (device_wifi)); + if (connection_activate != NULL) { + nm_client_activate_connection (client, + connection_activate, + device, NULL, + connection_activate_cb, device_wifi); + goto out; + } + + /* create one, as it's missing */ + g_debug ("no existing connection found for %s, creating", + ssid_target); + nm_client_add_and_activate_connection (client, + NULL, + device, object_path, + connection_add_activate_cb, device_wifi); +out: + g_free (ssid_target); + g_free (object_path); +} + +static gint +wireless_ap_model_sort_cb (GtkTreeModel *model, + GtkTreeIter *a, + GtkTreeIter *b, + gpointer user_data) +{ + gchar *str_a; + gchar *str_b; + gint strength_a; + gint strength_b; + gboolean active_a; + gboolean active_b; + gint retval; + + gtk_tree_model_get (model, a, + COLUMN_SORT, &str_a, + COLUMN_STRENGTH, &strength_a, + COLUMN_ACTIVE, &active_a, + -1); + gtk_tree_model_get (model, b, + COLUMN_SORT, &str_b, + COLUMN_STRENGTH, &strength_b, + COLUMN_ACTIVE, &active_b, + -1); + + /* special case blank entries to the bottom */ + if (g_strcmp0 (str_a, "") == 0) { + retval = 1; + goto out; + } + if (g_strcmp0 (str_b, "") == 0) { + retval = -1; + goto out; + } + + if (active_a) { + retval = -1; + goto out; + } + + if (active_b) { + retval = 1; + goto out; + } + + /* case sensitive search like before */ + g_debug ("compare %s (%d) with %s (%d)", str_a, strength_a, str_b, strength_b); + retval = strength_b - strength_a; + +out: + g_free (str_a); + g_free (str_b); + + return retval; +} + +static GByteArray * +ssid_to_byte_array (const gchar *ssid) +{ + guint32 len; + GByteArray *ba; + + len = strlen (ssid); + ba = g_byte_array_sized_new (len); + g_byte_array_append (ba, (guchar *)ssid, len); + + return ba; +} + +static gchar * +get_hostname (void) +{ + GDBusConnection *bus; + GVariant *res; + GVariant *inner; + gchar *str; + GError *error; + + error = NULL; + bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); + if (error != NULL) { + g_warning ("Failed to get system bus connection: %s", error->message); + g_error_free (error); + + return NULL; + } + res = g_dbus_connection_call_sync (bus, + "org.freedesktop.hostname1", + "/org/freedesktop/hostname1", + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new ("(ss)", + "org.freedesktop.hostname1", + "PrettyHostname"), + (GVariantType*)"(v)", + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_object_unref (bus); + + if (error != NULL) { + g_warning ("Getting pretty hostname failed: %s", error->message); + g_error_free (error); + } + + str = NULL; + + if (res != NULL) { + g_variant_get (res, "(v)", &inner); + str = g_variant_dup_string (inner, NULL); + g_variant_unref (res); + } + + if (str == NULL || *str == '\0') { + str = g_strdup (g_get_host_name ()); + } + + if (str == NULL || *str == '\0') { + str = g_strdup ("GNOME"); + } + + return str; +} + +static GByteArray * +generate_ssid_for_hotspot (NetDeviceWifi *device_wifi) +{ + GByteArray *ssid_array; + gchar *ssid; + + ssid = get_hostname (); + ssid_array = ssid_to_byte_array (ssid); + g_free (ssid); + + return ssid_array; +} + +static gchar * +generate_wep_key (NetDeviceWifi *device_wifi) +{ + gchar key[11]; + gint i; + const gchar *hexdigits = "0123456789abcdef"; + + /* generate a 10-digit hex WEP key */ + for (i = 0; i < 10; i++) { + gint digit; + digit = g_random_int_range (0, 16); + key[i] = hexdigits[digit]; + } + key[10] = 0; + + return g_strdup (key); +} + +static gboolean +is_hotspot_connection (NMConnection *connection) +{ + NMSettingConnection *sc; + NMSettingWireless *sw; + NMSettingIP4Config *sip; + + sc = nm_connection_get_setting_connection (connection); + if (g_strcmp0 (nm_setting_connection_get_connection_type (sc), "802-11-wireless") != 0) { + return FALSE; + } + sw = nm_connection_get_setting_wireless (connection); + if (g_strcmp0 (nm_setting_wireless_get_mode (sw), "adhoc") != 0) { + return FALSE; + } + if (g_strcmp0 (nm_setting_wireless_get_security (sw), "802-11-wireless-security") != 0) { + return FALSE; + } + sip = nm_connection_get_setting_ip4_config (connection); + if (g_strcmp0 (nm_setting_ip4_config_get_method (sip), "shared") != 0) { + return FALSE; + } + + return TRUE; +} + +static void +activate_cb (NMClient *client, + NMActiveConnection *connection, + GError *error, + NetDeviceWifi *device_wifi) +{ + if (error) { + g_warning ("Failed to add new connection: (%d) %s", + error->code, + error->message); + return; + } + + nm_device_wifi_refresh_ui (device_wifi); +} + +static void +activate_new_cb (NMClient *client, + NMActiveConnection *connection, + const gchar *path, + GError *error, + NetDeviceWifi *device_wifi) +{ + activate_cb (client, connection, error, device_wifi); +} + +static void +start_shared_connection (NetDeviceWifi *device_wifi) +{ + NMConnection *c; + NMConnection *tmp; + NMSettingConnection *sc; + NMSettingWireless *sw; + NMSettingIP4Config *sip; + NMSettingWirelessSecurity *sws; + NMDevice *device; + GByteArray *ssid_array; + gchar *wep_key; + const gchar *str_mac; + struct ether_addr *bin_mac; + GSList *connections; + GSList *filtered; + GSList *l; + NMClient *client; + NMRemoteSettings *remote_settings; + + device = net_device_get_nm_device (NET_DEVICE (device_wifi)); + g_assert (nm_device_get_device_type (device) == NM_DEVICE_TYPE_WIFI); + + remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi)); + connections = nm_remote_settings_list_connections (remote_settings); + filtered = nm_device_filter_connections (device, connections); + g_slist_free (connections); + c = NULL; + for (l = filtered; l; l = l->next) { + tmp = l->data; + if (is_hotspot_connection (tmp)) { + c = tmp; + break; + } + } + g_slist_free (filtered); + + client = net_object_get_client (NET_OBJECT (device_wifi)); + if (c != NULL) { + g_debug ("activate existing hotspot connection\n"); + nm_client_activate_connection (client, + c, + device, + NULL, + (NMClientActivateFn)activate_cb, + device_wifi); + return; + } + + g_debug ("create new hotspot connection\n"); + c = nm_connection_new (); + + sc = (NMSettingConnection *)nm_setting_connection_new (); + g_object_set (sc, + "type", "802-11-wireless", + "id", "Hotspot", + "autoconnect", FALSE, + NULL); + nm_connection_add_setting (c, (NMSetting *)sc); + + sw = (NMSettingWireless *)nm_setting_wireless_new (); + g_object_set (sw, + "mode", "adhoc", + "security", "802-11-wireless-security", + NULL); + + str_mac = nm_device_wifi_get_permanent_hw_address (NM_DEVICE_WIFI (device)); + bin_mac = ether_aton (str_mac); + if (bin_mac) { + GByteArray *hw_address; + + hw_address = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (hw_address, bin_mac->ether_addr_octet, ETH_ALEN); + g_object_set (sw, + "mac-address", hw_address, + NULL); + g_byte_array_unref (hw_address); + } + nm_connection_add_setting (c, (NMSetting *)sw); + + sip = (NMSettingIP4Config*) nm_setting_ip4_config_new (); + g_object_set (sip, "method", "shared", NULL); + nm_connection_add_setting (c, (NMSetting *)sip); + + ssid_array = generate_ssid_for_hotspot (device_wifi); + g_object_set (sw, + "ssid", ssid_array, + NULL); + g_byte_array_unref (ssid_array); + + sws = (NMSettingWirelessSecurity*) nm_setting_wireless_security_new (); + wep_key = generate_wep_key (device_wifi); + g_object_set (sws, + "key-mgmt", "none", + "wep-key0", wep_key, + "wep-key-type", NM_WEP_KEY_TYPE_KEY, + NULL); + g_free (wep_key); + nm_connection_add_setting (c, (NMSetting *)sws); + + nm_client_add_and_activate_connection (client, + c, + device, + NULL, + (NMClientAddActivateFn)activate_new_cb, + device_wifi); + + g_object_unref (c); +} + +static void +start_hotspot_response_cb (GtkWidget *dialog, gint response, NetDeviceWifi *device_wifi) +{ + if (response == GTK_RESPONSE_OK) { + start_shared_connection (device_wifi); + } + gtk_widget_destroy (dialog); +} + +static void +start_hotspot (GtkButton *button, NetDeviceWifi *device_wifi) +{ + NMDevice *device; + gboolean is_default; + const GPtrArray *connections; + const GPtrArray *devices; + NMActiveConnection *c; + NMAccessPoint *ap; + gchar *active_ssid; + gchar *warning; + gint i; + NMClient *client; + + warning = NULL; + + client = net_object_get_client (NET_OBJECT (device_wifi)); + device = net_device_get_nm_device (NET_DEVICE (device_wifi)); + connections = nm_client_get_active_connections (client); + if (connections == NULL || connections->len == 0) { + warning = g_strdup_printf ("%s\n\n%s", + _("Not connected to the internet."), + _("Create the hotspot anyway?")); + } else { + is_default = FALSE; + active_ssid = NULL; + for (i = 0; i < connections->len; i++) { + c = (NMActiveConnection *)connections->pdata[i]; + devices = nm_active_connection_get_devices (c); + if (devices && devices->pdata[0] == device) { + ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device)); + active_ssid = nm_utils_ssid_to_utf8 (nm_access_point_get_ssid (ap)); + is_default = nm_active_connection_get_default (c); + break; + } + } + + if (active_ssid != NULL) { + GString *str; + str = g_string_new (""); + g_string_append_printf (str, _("Disconnect from %s and create a new hotspot?"), active_ssid); + if (is_default) { + g_string_append (str, "\n\n"); + g_string_append (str, _("This is your only connection to the internet.")); + } + warning = g_string_free (str, FALSE); + } + } + + if (warning != NULL) { + GtkWidget *dialog; + GtkWidget *window; + CcNetworkPanel *panel; + + panel = net_object_get_panel (NET_OBJECT (device_wifi)); + window = gtk_widget_get_toplevel (GTK_WIDGET (panel)); + dialog = gtk_message_dialog_new (GTK_WINDOW (window), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_OTHER, + GTK_BUTTONS_NONE, + "%s", warning); + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + _("Create _Hotspot"), GTK_RESPONSE_OK, + NULL); + g_signal_connect (dialog, "response", + G_CALLBACK (start_hotspot_response_cb), device_wifi); + gtk_window_present (GTK_WINDOW (dialog)); + + return; + } + + /* if we get here, things look good to go ahead */ + start_shared_connection (device_wifi); +} + +static void +stop_shared_connection (NetDeviceWifi *device_wifi) +{ + const GPtrArray *connections; + const GPtrArray *devices; + NMDevice *device; + gint i; + NMActiveConnection *c; + NMClient *client; + + device = net_device_get_nm_device (NET_DEVICE (device_wifi)); + client = net_object_get_client (NET_OBJECT (device_wifi)); + connections = nm_client_get_active_connections (client); + for (i = 0; i < connections->len; i++) { + c = (NMActiveConnection *)connections->pdata[i]; + + devices = nm_active_connection_get_devices (c); + if (devices && devices->pdata[0] == device) { + nm_client_deactivate_connection (client, c); + break; + } + } + + nm_device_wifi_refresh_ui (device_wifi); +} + +static void +stop_hotspot_response_cb (GtkWidget *dialog, gint response, NetDeviceWifi *device_wifi) +{ + if (response == GTK_RESPONSE_OK) { + stop_shared_connection (device_wifi); + } + gtk_widget_destroy (dialog); +} + +static void +stop_hotspot (GtkButton *button, NetDeviceWifi *device_wifi) +{ + GtkWidget *dialog; + GtkWidget *window; + CcNetworkPanel *panel; + + panel = net_object_get_panel (NET_OBJECT (device_wifi)); + window = gtk_widget_get_toplevel (GTK_WIDGET (panel)); + dialog = gtk_message_dialog_new (GTK_WINDOW (window), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_OTHER, + GTK_BUTTONS_NONE, + _("Stop hotspot and disconnect any users?")); + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + _("_Stop Hotspot"), GTK_RESPONSE_OK, + NULL); + g_signal_connect (dialog, "response", + G_CALLBACK (stop_hotspot_response_cb), device_wifi); + gtk_window_present (GTK_WINDOW (dialog)); +} + +static void +edit_connection (GtkButton *button, NetDeviceWifi *device_wifi) +{ + net_object_edit (NET_OBJECT (device_wifi)); +} + +static void +net_device_wifi_constructed (GObject *object) +{ + NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (object); + NMClient *client; + + G_OBJECT_CLASS (net_device_wifi_parent_class)->constructed (object); + + client = net_object_get_client (NET_OBJECT (device_wifi)); + g_signal_connect (client, "notify::wireless-enabled", + G_CALLBACK (wireless_enabled_toggled), device_wifi); + + nm_device_wifi_refresh_ui (device_wifi); +} + +static void +net_device_wifi_finalize (GObject *object) +{ + NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (object); + NetDeviceWifiPrivate *priv = device_wifi->priv; + + g_object_unref (priv->builder); + + G_OBJECT_CLASS (net_device_wifi_parent_class)->finalize (object); +} + +static void +net_device_wifi_class_init (NetDeviceWifiClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NetObjectClass *parent_class = NET_OBJECT_CLASS (klass); + + object_class->finalize = net_device_wifi_finalize; + object_class->constructed = net_device_wifi_constructed; + parent_class->add_to_notebook = device_wifi_proxy_add_to_notebook; + parent_class->refresh = device_wifi_refresh; + g_type_class_add_private (klass, sizeof (NetDeviceWifiPrivate)); +} + +static void +net_device_wifi_init (NetDeviceWifi *device_wifi) +{ + GError *error = NULL; + GtkWidget *widget; + GtkCellRenderer *renderer; + GtkComboBox *combobox; + GtkTreeSortable *sortable; + + device_wifi->priv = NET_DEVICE_WIFI_GET_PRIVATE (device_wifi); + + device_wifi->priv->builder = gtk_builder_new (); + gtk_builder_add_from_file (device_wifi->priv->builder, + GNOMECC_UI_DIR "/network-wifi.ui", + &error); + if (error != NULL) { + g_warning ("Could not load interface file: %s", error->message); + g_error_free (error); + return; + } + + /* setup wifi combobox model */ + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "device_off_switch")); + g_signal_connect (widget, "notify::active", + G_CALLBACK (device_off_toggled), device_wifi); + + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "button_options")); + g_signal_connect (widget, "clicked", + G_CALLBACK (edit_connection), device_wifi); + + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "button_forget")); + g_signal_connect (widget, "clicked", + G_CALLBACK (forget_button_clicked_cb), device_wifi); + + /* setup wireless combobox model */ + combobox = GTK_COMBO_BOX (gtk_builder_get_object (device_wifi->priv->builder, + "combobox_network_name")); + g_signal_connect (combobox, "changed", + G_CALLBACK (wireless_ap_changed_cb), + device_wifi); + + /* sort networks in drop down */ + sortable = GTK_TREE_SORTABLE (gtk_builder_get_object (device_wifi->priv->builder, + "liststore_network")); + gtk_tree_sortable_set_sort_column_id (sortable, + COLUMN_SORT, + GTK_SORT_ASCENDING); + gtk_tree_sortable_set_sort_func (sortable, + COLUMN_SORT, + wireless_ap_model_sort_cb, + device_wifi, + NULL); + + renderer = panel_cell_renderer_mode_new (); + gtk_cell_renderer_set_padding (renderer, 4, 0); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox), + renderer, + FALSE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer, + "mode", COLUMN_MODE, + NULL); + + renderer = panel_cell_renderer_signal_new (); + gtk_cell_renderer_set_padding (renderer, 4, 0); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox), + renderer, + FALSE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer, + "signal", COLUMN_STRENGTH, + NULL); + + renderer = panel_cell_renderer_security_new (); + gtk_cell_renderer_set_padding (renderer, 4, 0); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox), + renderer, + FALSE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer, + "security", COLUMN_SECURITY, + NULL); + + + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "start_hotspot_button")); + g_signal_connect (widget, "clicked", + G_CALLBACK (start_hotspot), device_wifi); + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "stop_hotspot_button")); + g_signal_connect (widget, "clicked", + G_CALLBACK (stop_hotspot), device_wifi); + +} diff --git a/panels/network/net-device-wifi.h b/panels/network/net-device-wifi.h new file mode 100644 index 000000000..9ccee9f7a --- /dev/null +++ b/panels/network/net-device-wifi.h @@ -0,0 +1,58 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2011-2012 Richard Hughes + * + * Licensed under the GNU General Public License Version 2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __NET_DEVICE_WIFI_H +#define __NET_DEVICE_WIFI_H + +#include + +#include "net-device.h" + +G_BEGIN_DECLS + +#define NET_TYPE_DEVICE_WIFI (net_device_wifi_get_type ()) +#define NET_DEVICE_WIFI(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NET_TYPE_DEVICE_WIFI, NetDeviceWifi)) +#define NET_DEVICE_WIFI_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NET_TYPE_DEVICE_WIFI, NetDeviceWifiClass)) +#define NET_IS_DEVICE_WIFI(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NET_TYPE_DEVICE_WIFI)) +#define NET_IS_DEVICE_WIFI_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NET_TYPE_DEVICE_WIFI)) +#define NET_DEVICE_WIFI_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NET_TYPE_DEVICE_WIFI, NetDeviceWifiClass)) + +typedef struct _NetDeviceWifiPrivate NetDeviceWifiPrivate; +typedef struct _NetDeviceWifi NetDeviceWifi; +typedef struct _NetDeviceWifiClass NetDeviceWifiClass; + +struct _NetDeviceWifi +{ + NetDevice parent; + NetDeviceWifiPrivate *priv; +}; + +struct _NetDeviceWifiClass +{ + NetDeviceClass parent_class; +}; + +GType net_device_wifi_get_type (void); + +G_END_DECLS + +#endif /* __NET_DEVICE_WIFI_H */ + diff --git a/panels/network/network-wifi.ui b/panels/network/network-wifi.ui new file mode 100644 index 000000000..13579e2cb --- /dev/null +++ b/panels/network/network-wifi.ui @@ -0,0 +1,525 @@ + + + + + + + + + + + + + + + + + + + + + + + False + + + True + False + 12 + 6 + + + True + False + start + 10 + 6 + + + True + False + end + start + 1 + 48 + network-wireless + 6 + + + 0 + 0 + 1 + 1 + + + + + True + False + start + True + 3 + + + True + False + 0 + Wireless + end + + + + + + + False + False + 0 + + + + + True + False + 0 + Not connected + + + False + False + 1 + + + + + 1 + 0 + 1 + 1 + + + + + True + False + 1 + Hardware Address + label_mac + + + + 0 + 1 + 1 + 1 + + + + + True + False + 1 + IPv4 Address + label_ipv4 + + + + 0 + 5 + 1 + 1 + + + + + True + False + 1 + IPv6 Address + label_ipv6 + + + + 0 + 6 + 1 + 1 + + + + + True + False + 1 + Default Route + label_route + + + + 0 + 7 + 1 + 1 + + + + + True + False + 1 + 0 + DNS + label_dns + + + + 0 + 8 + 1 + 1 + + + + + True + False + 0 + AA:BB:CC:DD:55:66:77:88 + True + + + 1 + 1 + 2 + 1 + + + + + True + False + 0 + 127.0.0.1 + True + + + 1 + 5 + 2 + 1 + + + + + True + False + 0 + ::1 + True + + + 1 + 6 + 2 + 1 + + + + + True + False + 0 + 127.0.0.1 + True + + + 1 + 7 + 2 + 1 + + + + + True + False + 0 + 0 + 127.0.0.1 + True + True + + + 1 + 8 + 2 + 1 + + + + + True + False + end + start + + + True + True + end + start + + + + + 2 + 0 + 1 + 1 + + + + + True + False + 1 + Security + label_security + + + + 0 + 2 + 1 + 1 + + + + + True + False + 1 + _Network Name + True + combobox_network_name + + + + 0 + 3 + 1 + 1 + + + + + True + False + 1 + Network Name + + + + 0 + 9 + 1 + 1 + + + + + True + False + 1 + Security Key + + + + 0 + 10 + 1 + 1 + + + + + True + False + 0 + WPA + True + + + 1 + 2 + 2 + 1 + + + + + True + False + liststore_network + True + 1 + + + False + + + + + 1 + 3 + 2 + 1 + + + + + True + False + 0 + My Hot Spot + True + + + 1 + 9 + 2 + 1 + + + + + True + False + 0 + My Secret + True + + + 1 + 10 + 2 + 1 + + + + + _Forget Network + True + True + True + + + 1 + 4 + 2 + 1 + + + + + + + + True + True + 0 + + + + + True + False + 12 + + + _Use as Hotspot... + True + True + True + start + end + True + True + True + + + False + True + 0 + + + + + _Stop Hotspot... + True + True + start + end + True + True + True + 1 + + + False + True + 1 + + + + + _Options... + True + True + True + end + end + True + True + True + + + False + True + 2 + + + + + True + True + 1 + + + + + + + + + + + diff --git a/panels/network/network.ui b/panels/network/network.ui index b083dac74..44e2b0a8a 100644 --- a/panels/network/network.ui +++ b/panels/network/network.ui @@ -343,526 +343,6 @@ True True False - - - True - False - 12 - 6 - - - True - False - start - 10 - 6 - - - True - False - end - start - 1 - 48 - network-wireless - 6 - - - 0 - 0 - 1 - 1 - - - - - True - False - start - True - 3 - - - True - False - 0 - Wireless - end - - - - - - - False - False - 0 - - - - - True - False - 0 - Not connected - - - False - False - 1 - - - - - 1 - 0 - 1 - 1 - - - - - True - False - 1 - Hardware Address - label_wireless_mac - - - - 0 - 1 - 1 - 1 - - - - - True - False - 1 - IPv4 Address - label_wireless_ipv4 - - - - 0 - 5 - 1 - 1 - - - - - True - False - 1 - IPv6 Address - label_wireless_ipv6 - - - - 0 - 6 - 1 - 1 - - - - - True - False - 1 - Default Route - label_wireless_route - - - - 0 - 7 - 1 - 1 - - - - - True - False - 1 - 0 - DNS - label_wireless_dns - - - - 0 - 8 - 1 - 1 - - - - - True - False - 0 - AA:BB:CC:DD:55:66:77:88 - True - - - 1 - 1 - 2 - 1 - - - - - True - False - 0 - 127.0.0.1 - True - - - 1 - 5 - 2 - 1 - - - - - True - False - 0 - ::1 - True - - - 1 - 6 - 2 - 1 - - - - - True - False - 0 - 127.0.0.1 - True - - - 1 - 7 - 2 - 1 - - - - - True - False - 0 - 0 - 127.0.0.1 - True - True - - - 1 - 8 - 2 - 1 - - - - - True - False - end - start - - - False - True - True - end - start - False - - - Device Off - - - - - - - 2 - 0 - 1 - 1 - - - - - True - False - 1 - Security - label_wireless_security - - - - 0 - 2 - 1 - 1 - - - - - True - False - 1 - _Network Name - True - combobox_wireless_network_name - - - - 0 - 3 - 1 - 1 - - - - - True - False - 1 - Network Name - - - - 0 - 9 - 1 - 1 - - - - - True - False - 1 - Security Key - - - - 0 - 10 - 1 - 1 - - - - - True - False - 0 - WPA - True - - - 1 - 2 - 2 - 1 - - - - - True - False - liststore_wireless_network - True - 1 - - - False - - - - - 1 - 3 - 2 - 1 - - - - - True - False - 0 - My Hot Spot - True - - - 1 - 9 - 2 - 1 - - - - - True - False - 0 - My Secret - True - - - 1 - 10 - 2 - 1 - - - - - _Forget Network - True - False - True - True - - - 1 - 4 - 2 - 1 - - - - - True - True - 0 - - - - - True - False - 12 - - - _Use as Hotspot... - False - True - True - True - start - end - True - True - False - True - - - False - True - 0 - - - - - _Stop Hotspot... - False - True - True - start - end - True - True - False - True - 1 - - - False - True - 1 - - - - - _Options... - False - True - True - True - end - end - True - True - False - True - - - False - True - 2 - - - - - True - True - 1 - - - - - 1 - - - - - True - False - wireless - - - 1 - False - - True