static GPtrArray *
get_strongest_unique_aps (const GPtrArray *aps)
{
  const GByteArray *ssid;
  const GByteArray *ssid_tmp;
  GPtrArray *unique = NULL;
  gboolean add_ap;
  guint i;
  guint j;
  NMAccessPoint *ap;
  NMAccessPoint *ap_tmp;

  /* we will have multiple entries for typical hotspots,
   * just keep the one with the strongest signal
   */
  unique = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
  if (aps == NULL)
    goto out;

  for (i = 0; i < aps->len; i++) {
    ap = NM_ACCESS_POINT (g_ptr_array_index (aps, i));
    ssid = nm_access_point_get_ssid (ap);
    add_ap = TRUE;

    /* get already added list */
    for (j = 0; j < unique->len; j++) {
      ap_tmp = NM_ACCESS_POINT (g_ptr_array_index (unique, j));
      ssid_tmp = nm_access_point_get_ssid (ap_tmp);

      /* is this the same type and data? */
      if (nm_utils_same_ssid (ssid, ssid_tmp, TRUE)) {
        /* the new access point is stronger */
        if (nm_access_point_get_strength (ap) >
            nm_access_point_get_strength (ap_tmp)) {
          g_ptr_array_remove (unique, ap_tmp);
          add_ap = TRUE;
        } else {
          add_ap = FALSE;
        }
        break;
      }
    }
    if (add_ap) {
      g_ptr_array_add (unique, g_object_ref (ap));
    }
  }

 out:
  return unique;
}
static void
add_access_point (GisNetworkPage *page, NMAccessPoint *ap, NMAccessPoint *active)
{
  GisNetworkPagePrivate *priv = page->priv;
  const GByteArray *ssid;
  const gchar *ssid_text;
  const gchar *object_path;
  GtkTreeIter iter;
  gboolean activated, activating;

  ssid = nm_access_point_get_ssid (ap);
  object_path = nm_object_get_path (NM_OBJECT (ap));

  if (ssid == NULL)
    return;
  ssid_text = nm_utils_escape_ssid (ssid->data, ssid->len);

  if (active &&
      nm_utils_same_ssid (ssid, nm_access_point_get_ssid (active), TRUE)) {
    switch (nm_device_get_state (priv->nm_device))
      {
      case NM_DEVICE_STATE_PREPARE:
      case NM_DEVICE_STATE_CONFIG:
      case NM_DEVICE_STATE_NEED_AUTH:
      case NM_DEVICE_STATE_IP_CONFIG:
      case NM_DEVICE_STATE_SECONDARIES:
        activated = FALSE;
        activating = TRUE;
        break;
      case NM_DEVICE_STATE_ACTIVATED:
        activated = TRUE;
        activating = FALSE;
        break;
      default:
        activated = FALSE;
        activating = FALSE;
        break;
      }
  } else {
    activated = FALSE;
    activating = FALSE;
  }

  gtk_list_store_append (priv->ap_list, &iter);
  gtk_list_store_set (priv->ap_list, &iter,
                      PANEL_WIRELESS_COLUMN_ID, object_path,
                      PANEL_WIRELESS_COLUMN_TITLE, 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_ACTIVATING, activating,
                      PANEL_WIRELESS_COLUMN_ACTIVE, activated,
                      PANEL_WIRELESS_COLUMN_PULSE, priv->pulse,
                      -1);
  if (activating) {
    GtkTreePath *path;
    GtkTreeModel *model;

    model = (GtkTreeModel*)priv->ap_list;
    path = gtk_tree_model_get_path (model, &iter);
    priv->row = gtk_tree_row_reference_new (model, path);
    gtk_tree_path_free (path);

    g_timeout_add (160, bump_pulse, page);
  }
}
示例#3
0
static void
row_activated (GtkListBox *box,
               GtkListBoxRow *row,
               GisNetworkPage *page)
{
  GisNetworkPagePrivate *priv = gis_network_page_get_instance_private (page);
  gchar *object_path;
  GSList *list, *filtered, *l;
  NMConnection *connection;
  NMConnection *connection_to_activate;
  NMSettingWireless *setting;
  const GByteArray *ssid_target;
  const GByteArray *ssid;
  GtkWidget *child;

  if (priv->refreshing)
    return;

  child = gtk_bin_get_child (GTK_BIN (row));
  object_path = g_object_get_data (G_OBJECT (child), "object-path");
  ssid_target = g_object_get_data (G_OBJECT (child), "ssid");

  if (g_strcmp0 (object_path, "ap-other...") == 0) {
    connect_to_hidden_network (page);
    goto out;
  }

  list = nm_remote_settings_list_connections (priv->nm_settings);
  filtered = nm_device_filter_connections (priv->nm_device, list);

  connection_to_activate = NULL;

  for (l = filtered; l; l = l->next) {
    connection = NM_CONNECTION (l->data);
    setting = nm_connection_get_setting_wireless (connection);
    if (!NM_IS_SETTING_WIRELESS (setting))
      continue;

    ssid = nm_setting_wireless_get_ssid (setting);
    if (ssid == NULL)
      continue;

    if (nm_utils_same_ssid (ssid, ssid_target, TRUE)) {
      connection_to_activate = connection;
      break;
    }
  }
  g_slist_free (list);
  g_slist_free (filtered);

  if (connection_to_activate != NULL) {
    nm_client_activate_connection (priv->nm_client,
                                   connection_to_activate,
                                   priv->nm_device, NULL,
                                   connection_activate_cb, page);
    goto out;
  }

  nm_client_add_and_activate_connection (priv->nm_client,
                                         NULL,
                                         priv->nm_device, object_path,
                                         connection_add_activate_cb, page);

 out:
  refresh_wireless_list (page);
}
示例#4
0
static void
add_access_point (GisNetworkPage *page, NMAccessPoint *ap, NMAccessPoint *active)
{
  GisNetworkPagePrivate *priv = gis_network_page_get_instance_private (page);
  const GByteArray *ssid;
  gchar *ssid_text;
  const gchar *object_path;
  gboolean activated, activating;
  guint security;
  guint strength;
  const gchar *icon_name;
  GtkWidget *row;
  GtkWidget *widget;
  GtkWidget *box;

  ssid = nm_access_point_get_ssid (ap);
  object_path = nm_object_get_path (NM_OBJECT (ap));

  if (ssid == NULL)
    return;
  ssid_text = nm_utils_ssid_to_utf8 (ssid);

  if (active &&
      nm_utils_same_ssid (ssid, nm_access_point_get_ssid (active), TRUE)) {
    switch (nm_device_get_state (priv->nm_device))
      {
      case NM_DEVICE_STATE_PREPARE:
      case NM_DEVICE_STATE_CONFIG:
      case NM_DEVICE_STATE_NEED_AUTH:
      case NM_DEVICE_STATE_IP_CONFIG:
      case NM_DEVICE_STATE_SECONDARIES:
        activated = FALSE;
        activating = TRUE;
        break;
      case NM_DEVICE_STATE_ACTIVATED:
        activated = TRUE;
        activating = FALSE;
        break;
      default:
        activated = FALSE;
        activating = FALSE;
        break;
      }
  } else {
    activated = FALSE;
    activating = FALSE;
  }

  security = get_access_point_security (ap);
  strength = nm_access_point_get_strength (ap);

  row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
  gtk_widget_set_margin_start (row, 12);
  gtk_widget_set_margin_end (row, 12);
  widget = gtk_label_new (ssid_text);
  gtk_widget_set_margin_top (widget, 12);
  gtk_widget_set_margin_bottom (widget, 12);
  gtk_box_pack_start (GTK_BOX (row), widget, FALSE, FALSE, 0);

  if (activated) {
    widget = gtk_image_new_from_icon_name ("object-select-symbolic", GTK_ICON_SIZE_MENU);
    gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
    gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
    gtk_box_pack_start (GTK_BOX (row), widget, FALSE, FALSE, 0);
  }

  widget = gtk_spinner_new ();
  gtk_widget_set_no_show_all (widget, TRUE);
  if (activating) {
    gtk_widget_show (widget);
    gtk_spinner_start (GTK_SPINNER (widget));
  }
  gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
  gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
  gtk_box_pack_start (GTK_BOX (row), widget, FALSE, FALSE, 0);

  gtk_box_pack_start (GTK_BOX (row), gtk_label_new (""), TRUE, FALSE, 0);

  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
  gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
  gtk_size_group_add_widget (priv->icons, box);
  gtk_box_pack_start (GTK_BOX (row), box, FALSE, FALSE, 0);

  if (security != NM_AP_SEC_UNKNOWN &&
      security != NM_AP_SEC_NONE) {
    widget = gtk_image_new_from_icon_name ("network-wireless-encrypted-symbolic", GTK_ICON_SIZE_MENU);
  } else {
    widget = gtk_label_new ("");
  }
  gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);

  if (strength < 20)
    icon_name = "network-wireless-signal-none-symbolic";
  else if (strength < 40)
    icon_name = "network-wireless-signal-weak-symbolic";
  else if (strength < 50)
    icon_name = "network-wireless-signal-ok-symbolic";
  else if (strength < 80)
    icon_name = "network-wireless-signal-good-symbolic";
  else
    icon_name = "network-wireless-signal-excellent-symbolic";
  widget = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
  gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);

  gtk_widget_show_all (row);

  g_object_set_data (G_OBJECT (row), "object-path", (gpointer) object_path);
  g_object_set_data (G_OBJECT (row), "ssid", (gpointer) ssid);
  g_object_set_data (G_OBJECT (row), "strength", GUINT_TO_POINTER (strength));

  gtk_container_add (GTK_CONTAINER (priv->network_list), row);
}
示例#5
0
gboolean
nm_ap_check_compatible (NMAccessPoint *self,
                        NMConnection *connection)
{
	NMAccessPointPrivate *priv;
	NMSettingWireless *s_wireless;
	NMSettingWirelessSecurity *s_wireless_sec;
	GBytes *ssid;
	const char *mode;
	const char *band;
	const char *bssid;
	guint32 channel;

	g_return_val_if_fail (NM_IS_AP (self), FALSE);
	g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);

	priv = NM_AP_GET_PRIVATE (self);

	s_wireless = nm_connection_get_setting_wireless (connection);
	if (s_wireless == NULL)
		return FALSE;
	
	ssid = nm_setting_wireless_get_ssid (s_wireless);
	if (   (ssid && !priv->ssid)
	    || (priv->ssid && !ssid))
		return FALSE;

	if (   ssid && priv->ssid &&
	    !nm_utils_same_ssid (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid),
	                         priv->ssid->data, priv->ssid->len,
	                         TRUE))
		return FALSE;

	bssid = nm_setting_wireless_get_bssid (s_wireless);
	if (bssid && (!priv->address || !nm_utils_hwaddr_matches (bssid, -1, priv->address, -1)))
		return FALSE;

	mode = nm_setting_wireless_get_mode (s_wireless);
	if (mode) {
		if (!strcmp (mode, "infrastructure") && (priv->mode != NM_802_11_MODE_INFRA))
			return FALSE;
		if (!strcmp (mode, "adhoc") && (priv->mode != NM_802_11_MODE_ADHOC))
			return FALSE;
		if (   !strcmp (mode, "ap")
		    && (priv->mode != NM_802_11_MODE_INFRA || priv->hotspot != TRUE))
			return FALSE;
	}

	band = nm_setting_wireless_get_band (s_wireless);
	if (band) {
		guint ap_band = freq_to_band (priv->freq);

		if (!strcmp (band, "a") && ap_band != 5)
			return FALSE;
		else if (!strcmp (band, "bg") && ap_band != 2)
			return FALSE;
	}

	channel = nm_setting_wireless_get_channel (s_wireless);
	if (channel) {
		guint32 ap_chan = nm_utils_wifi_freq_to_channel (priv->freq);

		if (channel != ap_chan)
			return FALSE;
	}

	s_wireless_sec = nm_connection_get_setting_wireless_security (connection);

	return nm_setting_wireless_ap_security_compatible (s_wireless,
	                                                   s_wireless_sec,
	                                                   priv->flags,
	                                                   priv->wpa_flags,
	                                                   priv->rsn_flags,
	                                                   priv->mode);
}
示例#6
0
NMAccessPoint *
nm_ap_match_in_list (NMAccessPoint *find_ap,
                     GSList *ap_list,
                     gboolean strict_match)
{
	GSList *iter;

	g_return_val_if_fail (find_ap != NULL, NULL);

	for (iter = ap_list; iter; iter = g_slist_next (iter)) {
		NMAccessPoint * list_ap = NM_AP (iter->data);
		const GByteArray * list_ssid = nm_ap_get_ssid (list_ap);
		const struct ether_addr * list_addr = nm_ap_get_address (list_ap);

		const GByteArray * find_ssid = nm_ap_get_ssid (find_ap);
		const struct ether_addr * find_addr = nm_ap_get_address (find_ap);

		/* SSID match; if both APs are hiding their SSIDs,
		 * let matching continue on BSSID and other properties
		 */
		if (   (!list_ssid && find_ssid)
		    || (list_ssid && !find_ssid)
		    || !nm_utils_same_ssid (list_ssid, find_ssid, TRUE))
			continue;

		/* BSSID match */
		if (   (strict_match || nm_ethernet_address_is_valid (find_addr))
		    && nm_ethernet_address_is_valid (list_addr)
		    && memcmp (list_addr->ether_addr_octet, 
		               find_addr->ether_addr_octet,
		               ETH_ALEN) != 0) {
			continue;
		}

		/* mode match */
		if (nm_ap_get_mode (list_ap) != nm_ap_get_mode (find_ap))
			continue;

		/* Frequency match */
		if (nm_ap_get_freq (list_ap) != nm_ap_get_freq (find_ap))
			continue;

		/* AP flags */
		if (nm_ap_get_flags (list_ap) != nm_ap_get_flags (find_ap))
			continue;

		if (strict_match) {
			if (nm_ap_get_wpa_flags (list_ap) != nm_ap_get_wpa_flags (find_ap))
				continue;

			if (nm_ap_get_rsn_flags (list_ap) != nm_ap_get_rsn_flags (find_ap))
				continue;
		} else {
			NM80211ApSecurityFlags list_wpa_flags = nm_ap_get_wpa_flags (list_ap);
			NM80211ApSecurityFlags find_wpa_flags = nm_ap_get_wpa_flags (find_ap);
			NM80211ApSecurityFlags list_rsn_flags = nm_ap_get_rsn_flags (list_ap);
			NM80211ApSecurityFlags find_rsn_flags = nm_ap_get_rsn_flags (find_ap);

			/* Just ensure that there is overlap in the capabilities */
			if (   !capabilities_compatible (list_wpa_flags, find_wpa_flags)
			    && !capabilities_compatible (list_rsn_flags, find_rsn_flags))
				continue;
		}

		return list_ap;
	}

	return NULL;
}
示例#7
0
gboolean
nm_ap_check_compatible (NMAccessPoint *self,
                        NMConnection *connection)
{
	NMAccessPointPrivate *priv;
	NMSettingWireless *s_wireless;
	NMSettingWirelessSecurity *s_wireless_sec;
	const char *mode;
	const char *band;
	const GByteArray *bssid;
	guint32 channel;

	g_return_val_if_fail (NM_IS_AP (self), FALSE);
	g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);

	priv = NM_AP_GET_PRIVATE (self);

	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
	if (s_wireless == NULL)
		return FALSE;
	
	if (!nm_utils_same_ssid (nm_setting_wireless_get_ssid (s_wireless), priv->ssid, TRUE))
		return FALSE;

	bssid = nm_setting_wireless_get_bssid (s_wireless);
	if (bssid && memcmp (bssid->data, &priv->address, ETH_ALEN))
		return FALSE;

	mode = nm_setting_wireless_get_mode (s_wireless);
	if (mode) {
		if (!strcmp (mode, "infrastructure") && (priv->mode != NM_802_11_MODE_INFRA))
			return FALSE;
		if (!strcmp (mode, "adhoc") && (priv->mode != NM_802_11_MODE_ADHOC))
			return FALSE;
	}

	band = nm_setting_wireless_get_band (s_wireless);
	if (band) {
		if (!strcmp (band, "a")) {
			if (priv->freq < 4915 || priv->freq > 5825)
				return FALSE;
		} else if (!strcmp (band, "bg")) {
			if (priv->freq < 2412 || priv->freq > 2484)
				return FALSE;
		}
	}

	channel = nm_setting_wireless_get_channel (s_wireless);
	if (channel) {
		guint32 ap_chan = nm_utils_wifi_freq_to_channel (priv->freq);

		if (channel != ap_chan)
			return FALSE;
	}

	s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection,
	                                                                          NM_TYPE_SETTING_WIRELESS_SECURITY);

	return nm_setting_wireless_ap_security_compatible (s_wireless,
	                                                   s_wireless_sec,
	                                                   nm_ap_get_flags (self),
	                                                   nm_ap_get_wpa_flags (self),
	                                                   nm_ap_get_rsn_flags (self),
	                                                   nm_ap_get_mode (self));
}