2007-09-10 Dan Williams <dcbw@redhat.com>

* include/NetworkManager.h
		- Kill NMNetworkType; AP types don't matter any more

	* src/NetworkManagerAPList.c
	  src/NetworkManagerAPList.h
	  src/Makefile.am
		- Kill; NMAccessPointList has outlived it's usefulness

	* src/NetworkManagerAP.c
	  src/NetworkManagerAP.h
		- (match_cipher, security_compatible, nm_ap_check_compatible): new
			functions; check if an NMConnection object is compatible with the
			settings of this AP
		- (freq_to_channel, channel_to_freq): utility functions for
			channel <-> frequency conversion

	* src/nm-device.c
	  src/nm-device.h
		- (nm_device_get_best_connection): pass the specific object around
			 (which might be the object path of a specific AP to connect to).
			 The get_best_connection() call should populate this on return
			 if needed (wireless does).

	* src/nm-device-802-3-ethernet.c
		- (real_get_best_connection): handle specific_object argument

	* src/NetworkManager.c
	  src/NetworkManagerMain.h
		- Remove unused includes

	* src/nm-device-802-11-wireless.c
	  src/nm-device-802-11-wireless.h
		- Convert the ap_list into a GSList from an NMAccessPointList
		- No need for caching the 'activation_ap' since this is now determined
			from the specific_object of the activation request, which is
			populated from the get_best_connection() call or from a user request
		- (nm_device_802_11_wireless_update_bssid): fix warning
		- (get_wireless_capabilities): fix error message format arguments
		- (nm_device_802_11_wireless_copy_allowed_to_dev_list): remove, unused
		- (find_best_connection, real_get_best_connection): implement
		- (ap_list_get_ap_by_ssid, nm_device_802_11_wireless_ap_list_print):
			move here from NetworkManagerAPList
		- (ap_need_secrets): remove; moved to nm-connection.c where it belongs
		- (real_act_stage1_prepare): just ensure an AP exists, connection is
			already verified earlier
		- (real_act_stage2_config): use nm_connection_need_secrets()

	* src/NetworkManagerPolicy.c
		- (nm_policy_auto_get_best_device): handle specific objects
		- (create_connection): remove; automatic connection creation functionality
			is handled by the Connection objects
		- (nm_policy_device_change_check): handle specific_object

	* libnm-util/nm-connection.c
		- (wireless_sec_need_secrets, nm_connection_need_secrets): implement



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2778 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2007-09-10 19:11:40 +00:00
parent 0b94b3d318
commit 4c028c7cef
17 changed files with 621 additions and 1023 deletions

View File

@@ -1,3 +1,61 @@
2007-09-10 Dan Williams <dcbw@redhat.com>
* include/NetworkManager.h
- Kill NMNetworkType; AP types don't matter any more
* src/NetworkManagerAPList.c
src/NetworkManagerAPList.h
src/Makefile.am
- Kill; NMAccessPointList has outlived it's usefulness
* src/NetworkManagerAP.c
src/NetworkManagerAP.h
- (match_cipher, security_compatible, nm_ap_check_compatible): new
functions; check if an NMConnection object is compatible with the
settings of this AP
- (freq_to_channel, channel_to_freq): utility functions for
channel <-> frequency conversion
* src/nm-device.c
src/nm-device.h
- (nm_device_get_best_connection): pass the specific object around
(which might be the object path of a specific AP to connect to).
The get_best_connection() call should populate this on return
if needed (wireless does).
* src/nm-device-802-3-ethernet.c
- (real_get_best_connection): handle specific_object argument
* src/NetworkManager.c
src/NetworkManagerMain.h
- Remove unused includes
* src/nm-device-802-11-wireless.c
src/nm-device-802-11-wireless.h
- Convert the ap_list into a GSList from an NMAccessPointList
- No need for caching the 'activation_ap' since this is now determined
from the specific_object of the activation request, which is
populated from the get_best_connection() call or from a user request
- (nm_device_802_11_wireless_update_bssid): fix warning
- (get_wireless_capabilities): fix error message format arguments
- (nm_device_802_11_wireless_copy_allowed_to_dev_list): remove, unused
- (find_best_connection, real_get_best_connection): implement
- (ap_list_get_ap_by_ssid, nm_device_802_11_wireless_ap_list_print):
move here from NetworkManagerAPList
- (ap_need_secrets): remove; moved to nm-connection.c where it belongs
- (real_act_stage1_prepare): just ensure an AP exists, connection is
already verified earlier
- (real_act_stage2_config): use nm_connection_need_secrets()
* src/NetworkManagerPolicy.c
- (nm_policy_auto_get_best_device): handle specific objects
- (create_connection): remove; automatic connection creation functionality
is handled by the Connection objects
- (nm_policy_device_change_check): handle specific_object
* libnm-util/nm-connection.c
- (wireless_sec_need_secrets, nm_connection_need_secrets): implement
2007-09-10 Dan Williams <dcbw@redhat.com>
* src/nm-manager.c

View File

@@ -117,18 +117,6 @@ typedef enum NMDeviceType
#define NM_802_11_AP_SEC_KEY_MGMT_802_1X 0x00000200
/*
* Wireless network types
*/
typedef enum NMNetworkType
{
NETWORK_TYPE_UNKNOWN = 0,
NETWORK_TYPE_ALLOWED,
NETWORK_TYPE_INVALID,
NETWORK_TYPE_DEVICE
} NMNetworkType;
/*
* Device states. Will obsolete NMActStage soon.
*/

View File

@@ -1,5 +1,6 @@
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include <string.h>
#include "nm-connection.h"
typedef struct {
@@ -89,7 +90,7 @@ nm_connection_get_setting (NMConnection *connection, const char *setting_name)
{
NMConnectionPrivate *priv;
g_return_if_fail (NM_IS_CONNECTION (connection));
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
g_return_val_if_fail (setting_name != NULL, NULL);
priv = NM_CONNECTION_GET_PRIVATE (connection);
@@ -110,13 +111,93 @@ nm_connection_compare (NMConnection *connection, NMConnection *other)
return FALSE;
}
gboolean
nm_connection_have_secrets (NMConnection *connection)
static GPtrArray *
wireless_sec_need_secrets (NMSettingWirelessSecurity *sec)
{
/* FIXME: go through Settings objects and determine if there are any
* secrets required.
*/
return FALSE;
GPtrArray * secrets;
secrets = g_ptr_array_sized_new (4);
if (!secrets) {
g_warning ("Not enough memory to create required secrets array.");
return NULL;
}
/* Static WEP */
if (strcmp (sec->key_mgmt, "none") == 0) {
if (!sec->wep_key0) {
g_ptr_array_add (secrets, "wep_key0");
return secrets;
}
if (sec->wep_tx_keyidx == 1 && !sec->wep_key1) {
g_ptr_array_add (secrets, "wep_key1");
return secrets;
}
if (sec->wep_tx_keyidx == 2 && !sec->wep_key2) {
g_ptr_array_add (secrets, "wep_key2");
return secrets;
}
if (sec->wep_tx_keyidx == 3 && !sec->wep_key3) {
g_ptr_array_add (secrets, "wep_key3");
return secrets;
}
goto no_secrets;
}
if ( (strcmp (sec->key_mgmt, "wpa-none") == 0)
|| (strcmp (sec->key_mgmt, "wpa-psk") == 0)) {
if (!sec->psk) {
g_ptr_array_add (secrets, "psk");
return secrets;
}
goto no_secrets;
}
if (strcmp (sec->key_mgmt, "wpa-eap") == 0) {
// FIXME: implement
goto no_secrets;
}
no_secrets:
if (secrets)
g_ptr_array_free (secrets, TRUE);
return NULL;
}
const char *
nm_connection_need_secrets (NMConnection *connection)
{
NMSettingConnection *s_connection;
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
s_connection = (NMSettingConnection *) nm_connection_get_setting (connection, "connection");
if (!s_connection)
return NULL;
/* Wireless */
if (strcmp (s_connection->devtype, "802-11-wireless") == 0) {
NMSettingWireless *s_wireless;
NMSettingWirelessSecurity *s_wireless_sec;
GPtrArray * secrets = NULL;
s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, "802-11-wireless");
if (!s_wireless || !s_wireless->security)
return NULL;
s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, "802-11-wireless-security");
if (!s_wireless_sec)
return NULL;
secrets = wireless_sec_need_secrets (s_wireless_sec);
if (secrets) {
// FIXME: modify NeedSecrets message to include the actual secrets
// required rather than just requesting all secrets for the setting
g_ptr_array_free (secrets, TRUE);
return "802-11-wireless-security";
}
}
return NULL;
}
static void

View File

@@ -35,7 +35,7 @@ NMSetting *nm_connection_get_setting (NMConnection *connection,
gboolean nm_connection_compare (NMConnection *connection,
NMConnection *other);
gboolean nm_connection_have_secrets (NMConnection *connection);
const char * nm_connection_need_secrets (NMConnection *connection);
GHashTable *nm_connection_to_hash (NMConnection *connection);
void nm_connection_dump (NMConnection *connection);

View File

@@ -25,8 +25,6 @@ NetworkManager_SOURCES = \
nm-device-802-11-wireless.h \
NetworkManagerAP.c \
NetworkManagerAP.h \
NetworkManagerAPList.c \
NetworkManagerAPList.h \
NetworkManagerDbusUtils.c \
NetworkManagerDbusUtils.h \
NetworkManagerDialup.h \

View File

@@ -47,8 +47,6 @@
#include "nm-device-802-3-ethernet.h"
#include "nm-device-802-11-wireless.h"
#include "NetworkManagerPolicy.h"
#include "NetworkManagerAP.h"
#include "NetworkManagerAPList.h"
#include "NetworkManagerSystem.h"
#include "nm-named-manager.h"
#include "nm-dbus-vpn.h"

View File

@@ -1022,3 +1022,257 @@ nm_ap_add_security_from_ie (guint32 flags,
return flags;
}
static gboolean
match_cipher (const char * cipher,
const char * expected,
guint32 wpa_flags,
guint32 rsn_flags,
guint32 flag)
{
if (strcmp (cipher, expected) != 0)
return FALSE;
if (!(wpa_flags & flag) && !(rsn_flags & flag))
return FALSE;
return TRUE;
}
static gboolean
security_compatible (NMAccessPoint *self,
NMConnection *connection,
NMSettingWireless *s_wireless)
{
NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE (self);
NMSettingWirelessSecurity *s_wireless_sec;
guint32 flags = priv->flags;
guint32 wpa_flags = priv->wpa_flags;
guint32 rsn_flags = priv->rsn_flags;
if (!s_wireless->security) {
if ( (flags & NM_802_11_AP_FLAGS_PRIVACY)
|| (wpa_flags != NM_802_11_AP_SEC_NONE)
|| (rsn_flags != NM_802_11_AP_SEC_NONE))
return FALSE;
return TRUE;
}
if (strcmp (s_wireless->security, "802-11-wireless-security") != 0)
return FALSE;
s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, "802-11-wireless-security");
if (s_wireless_sec == NULL || !s_wireless_sec->key_mgmt)
return FALSE;
/* Static WEP */
if (!strcmp (s_wireless_sec->key_mgmt, "none")) {
if ( !(flags & NM_802_11_AP_FLAGS_PRIVACY)
|| (wpa_flags != NM_802_11_AP_SEC_NONE)
|| (rsn_flags != NM_802_11_AP_SEC_NONE))
return FALSE;
return TRUE;
}
/* Adhoc WPA */
if (!strcmp (s_wireless_sec->key_mgmt, "wpa-none")) {
if (priv->mode != IW_MODE_ADHOC)
return FALSE;
// FIXME: validate ciphers if the BSSID actually puts WPA/RSN IE in
// it's beacon
return TRUE;
}
/* Stuff after this point requires infrastructure */
if (priv->mode != IW_MODE_INFRA)
return FALSE;
/* Dynamic WEP or LEAP/Network EAP */
if (!strcmp (s_wireless_sec->key_mgmt, "ieee8021x")) {
// FIXME: should we allow APs that advertise WPA/RSN support here?
if ( !(flags & NM_802_11_AP_FLAGS_PRIVACY)
|| (wpa_flags != NM_802_11_AP_SEC_NONE)
|| (rsn_flags != NM_802_11_AP_SEC_NONE))
return FALSE;
return TRUE;
}
/* WPA[2]-PSK */
if (!strcmp (s_wireless_sec->key_mgmt, "wpa-psk")) {
GSList * elt;
gboolean found = FALSE;
if (!s_wireless_sec->pairwise || !s_wireless_sec->group)
return FALSE;
if ( !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)
&& !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK))
return FALSE;
// FIXME: should handle WPA and RSN separately here to ensure that
// if the Connection only uses WPA we don't match a cipher against
// the AP's RSN IE instead
/* Match at least one pairwise cipher with AP's capability */
for (elt = s_wireless_sec->pairwise; elt; elt = g_slist_next (elt)) {
if ((found = match_cipher (elt->data, "tkip", wpa_flags, rsn_flags, NM_802_11_AP_SEC_PAIR_TKIP)))
break;
if ((found = match_cipher (elt->data, "ccmp", wpa_flags, rsn_flags, NM_802_11_AP_SEC_PAIR_CCMP)))
break;
}
if (!found)
return FALSE;
/* Match at least one group cipher with AP's capability */
for (elt = s_wireless_sec->group; elt; elt = g_slist_next (elt)) {
if ((found = match_cipher (elt->data, "wep40", wpa_flags, rsn_flags, NM_802_11_AP_SEC_GROUP_WEP40)))
break;
if ((found = match_cipher (elt->data, "wep104", wpa_flags, rsn_flags, NM_802_11_AP_SEC_GROUP_WEP104)))
break;
if ((found = match_cipher (elt->data, "tkip", wpa_flags, rsn_flags, NM_802_11_AP_SEC_GROUP_TKIP)))
break;
if ((found = match_cipher (elt->data, "ccmp", wpa_flags, rsn_flags, NM_802_11_AP_SEC_GROUP_CCMP)))
break;
}
if (!found)
return FALSE;
return TRUE;
}
if (!strcmp (s_wireless_sec->key_mgmt, "wpa-eap")) {
// FIXME: implement
}
return FALSE;
}
gboolean
nm_ap_check_compatible (NMAccessPoint *self,
NMConnection *connection)
{
NMAccessPointPrivate *priv;
NMSettingWireless *s_wireless;
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 = (NMSettingWireless *) nm_connection_get_setting (connection, "802-11-wireless");
if (s_wireless == NULL)
return FALSE;
if (!nm_utils_same_ssid (s_wireless->ssid, priv->ssid, TRUE))
return FALSE;
if (s_wireless->bssid) {
if (memcmp (s_wireless->bssid->data, &priv->address, ETH_ALEN))
return FALSE;
}
if (s_wireless->mode) {
if ( !strcmp (s_wireless->mode, "infrastructure")
&& (priv->mode != IW_MODE_INFRA))
return FALSE;
if ( !strcmp (s_wireless->mode, "adhoc")
&& (priv->mode != IW_MODE_ADHOC))
return FALSE;
}
if (s_wireless->band) {
if (!strcmp (s_wireless->band, "a")) {
if (priv->freq < 5170 || priv->freq > 5825)
return FALSE;
} else if (!strcmp (s_wireless->band, "bg")) {
if (priv->freq < 2412 || priv->freq > 2472)
return FALSE;
}
}
if (s_wireless->channel) {
guint32 ap_chan = freq_to_channel (priv->freq);
if (s_wireless->channel != ap_chan)
return FALSE;
}
return security_compatible (self, connection, s_wireless);
}
struct cf_pair {
guint32 chan;
double freq;
};
static struct cf_pair cf_table[46] = {
/* B/G band */
{ 1, 2412 },
{ 2, 2417 },
{ 3, 2422 },
{ 4, 2427 },
{ 5, 2432 },
{ 6, 2437 },
{ 7, 2442 },
{ 8, 2447 },
{ 9, 2452 },
{ 10, 2457 },
{ 11, 2462 },
{ 12, 2467 },
{ 13, 2472 },
/* A band */
{ 34, 5170 },
{ 36, 5180 },
{ 38, 5190 },
{ 40, 5200 },
{ 42, 5210 },
{ 44, 5220 },
{ 46, 5230 },
{ 48, 5240 },
{ 50, 5250 },
{ 52, 5260 },
{ 56, 5280 },
{ 58, 5290 },
{ 60, 5300 },
{ 64, 5320 },
{ 100, 5500 },
{ 104, 5520 },
{ 108, 5540 },
{ 112, 5560 },
{ 116, 5580 },
{ 120, 5600 },
{ 124, 5620 },
{ 128, 5640 },
{ 132, 5660 },
{ 136, 5680 },
{ 140, 5700 },
{ 149, 5745 },
{ 152, 5760 },
{ 153, 5765 },
{ 157, 5785 },
{ 160, 5800 },
{ 161, 5805 },
{ 165, 5825 },
{ 0, -1 }
};
guint32
freq_to_channel (double freq)
{
int i = 0;
while (cf_table[i].chan && (cf_table[i].freq != freq))
i++;
return cf_table[i].chan;
}
double
channel_to_freq (guint32 channel)
{
int i = 0;
while (cf_table[i].chan && (cf_table[i].chan != channel))
i++;
return cf_table[i].freq;
}

View File

@@ -27,6 +27,7 @@
#include <glib-object.h>
#include <time.h>
#include "NetworkManager.h"
#include "nm-connection.h"
#define NM_TYPE_AP (nm_ap_get_type ())
#define NM_AP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_AP, NMAccessPoint))
@@ -116,6 +117,9 @@ guint32 nm_ap_add_security_from_ie (guint32 flags,
const guint8 *wpa_ie,
guint32 length);
gboolean nm_ap_check_compatible (NMAccessPoint *self,
NMConnection *connection);
void nm_ap_print_self (NMAccessPoint *ap, const char * prefix);
/*
@@ -125,4 +129,7 @@ void nm_ap_print_self (NMAccessPoint *ap, const char * prefix);
*/
gboolean nm_ap_has_manufacturer_default_ssid (NMAccessPoint *ap);
guint32 freq_to_channel (double freq);
double channel_to_freq (guint32 channel);
#endif /* NM_ACCESS_POINT_H */

View File

@@ -1,531 +0,0 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2004 Red Hat, Inc.
*/
#include <glib.h>
#include <dbus/dbus-glib.h>
#include <netinet/ether.h>
#include "NetworkManagerAP.h"
#include "NetworkManagerAPList.h"
#include "NetworkManagerUtils.h"
#include "nm-utils.h"
#include "nm-dbus-manager.h"
struct NMAccessPointList
{
guint refcount;
NMNetworkType type;
GSList * ap_list;
};
/*
* nm_ap_list_new
*
* Creates a new empty access point list
*
*/
NMAccessPointList *nm_ap_list_new (NMNetworkType type)
{
NMAccessPointList *list = g_slice_new0 (NMAccessPointList);
nm_ap_list_ref (list);
list->type = type;
return list;
}
/*
* nm_ap_list_ref
*
* Increases the refcount of the ap list
*
*/
void nm_ap_list_ref (NMAccessPointList *list)
{
g_return_if_fail (list != NULL);
list->refcount++;
}
/*
* nm_ap_list_unref
*
* Decreases the refcount of the ap list, and if it reaches
* 0 frees the structure.
*
*/
void nm_ap_list_unref (NMAccessPointList *list)
{
if (!list)
return;
list->refcount--;
if (list->refcount <= 0) {
g_slist_foreach (list->ap_list, (GFunc) g_object_unref, NULL);
g_slist_free (list->ap_list);
g_slice_free (NMAccessPointList, list);
}
}
/*
* nm_ap_list_size
*
* Return size of the access point list
*
*/
guint nm_ap_list_size (NMAccessPointList *list)
{
g_return_val_if_fail (list != NULL, 0);
return g_slist_length (list->ap_list);
}
/*
* nm_ap_list_is_empty
*
* Returns whether or not the access point list has any access points
* in it.
*
*/
gboolean nm_ap_list_is_empty (NMAccessPointList *list)
{
return ((list->ap_list == NULL));
}
/*
* nm_ap_list_append_ap
*
* Helper to append an AP to an ap list of a certain type.
*
*/
void nm_ap_list_append_ap (NMAccessPointList *list, NMAccessPoint *ap)
{
g_return_if_fail (list != NULL);
g_return_if_fail (ap != NULL);
list->ap_list = g_slist_append (list->ap_list, g_object_ref (ap));
}
/*
* nm_ap_list_remove_ap
*
* Helper to remove an AP to an ap list of a certain type.
*
*/
void nm_ap_list_remove_ap (NMAccessPointList *list, NMAccessPoint *ap)
{
GSList *elt = NULL;
g_return_if_fail (list != NULL);
g_return_if_fail (ap != NULL);
for (elt = list->ap_list; elt; elt = g_slist_next (elt)) {
NMAccessPoint * list_ap = (NMAccessPoint *) elt->data;
if (list_ap == ap) {
list->ap_list = g_slist_remove_link (list->ap_list, elt);
g_object_unref (list_ap);
g_slist_free (elt);
break;
}
}
}
/*
* nm_ap_list_remove_ap_by_ssid
*
* Helper to remove an AP from an AP list by the AP's SSID.
*
*/
void
nm_ap_list_remove_ap_by_ssid (NMAccessPointList *list, const GByteArray * ssid)
{
GSList * elt = NULL;
g_return_if_fail (list != NULL);
g_return_if_fail (ssid != NULL);
for (elt = list->ap_list; elt; elt = g_slist_next (elt)) {
NMAccessPoint * list_ap = (NMAccessPoint *) elt->data;
if (nm_utils_same_ssid (nm_ap_get_ssid (list_ap), ssid, TRUE)) {
list->ap_list = g_slist_remove_link (list->ap_list, elt);
g_object_unref (list_ap);
g_slist_free (elt);
break;
}
}
}
/* nm_ap_list_remove_duplicate_ssids
*
*/
void nm_ap_list_remove_duplicate_ssids (NMAccessPointList *list)
{
NMAccessPoint *removal_ap;
NMAccessPoint *list_ap_max;
GSList *elt_i = NULL;
GSList *elt_j = NULL;
GSList *elt_max = NULL;
GSList *removal_list = NULL;
GSList *elt;
gint8 max_strength = 0;
gint8 strengthj = 0;
g_return_if_fail (list != NULL);
for (elt_i = list->ap_list; elt_i; elt_i = g_slist_next (elt_i)) {
NMAccessPoint * list_ap_i = (NMAccessPoint *) elt_i->data;
const GByteArray * list_ap_i_ssid = nm_ap_get_ssid (list_ap_i);
gboolean found = FALSE;
for (elt_j = list->ap_list; elt_j < elt_i; elt_j = g_slist_next (elt_j)) {
NMAccessPoint * list_ap_j = (NMAccessPoint *) elt_j->data;
const GByteArray * list_ap_j_ssid = nm_ap_get_ssid (list_ap_j);
if ((found = nm_utils_same_ssid (list_ap_i_ssid, list_ap_j_ssid, TRUE)))
break;
}
if (found)
continue;
elt_max = elt_i;
list_ap_max = (NMAccessPoint *)(elt_i->data);
max_strength = nm_ap_get_strength (list_ap_i);
for (elt_j = g_slist_next (elt_i); elt_j; elt_j = g_slist_next (elt_j)) {
NMAccessPoint *list_ap_j = (NMAccessPoint *) elt_j->data;
const GByteArray * list_ap_j_ssid = nm_ap_get_ssid (list_ap_j);
strengthj = nm_ap_get_strength (list_ap_j);
if (nm_utils_same_ssid (list_ap_i_ssid, list_ap_j_ssid, TRUE)) {
if (strengthj > max_strength) {
removal_list = g_slist_append (removal_list, list_ap_max);
list_ap_max = list_ap_j;
max_strength = strengthj;
} else {
removal_list = g_slist_append (removal_list, list_ap_j);
}
}
}
}
for (elt = removal_list; elt; elt = g_slist_next (elt)) {
if ((removal_ap = (NMAccessPoint *)(elt->data)))
nm_ap_list_remove_ap (list, removal_ap);
}
g_slist_free (removal_list);
}
/*
* nm_ap_list_get_ap_by_ssid
*
* Search through an access point list and return the access point
* that has a given SSID.
*
*/
NMAccessPoint *
nm_ap_list_get_ap_by_ssid (NMAccessPointList *list, const GByteArray * ssid)
{
NMAccessPoint *ap;
NMAccessPoint *found_ap = NULL;
NMAPListIter *iter;
if (!ssid || !list)
return NULL;
if (!(iter = nm_ap_list_iter_new (list)))
return NULL;
while ((ap = nm_ap_list_iter_next (iter))) {
const GByteArray * ap_ssid = nm_ap_get_ssid (ap);
if (ap_ssid && nm_utils_same_ssid (ap_ssid, ssid, TRUE)) {
found_ap = ap;
break;
}
}
nm_ap_list_iter_free (iter);
return found_ap;
}
/*
* nm_ap_list_get_ap_by_address
*
* Search through an access point list and return the access point
* that has a given AP address.
*
*/
NMAccessPoint *nm_ap_list_get_ap_by_address (NMAccessPointList *list, const struct ether_addr *addr)
{
NMAccessPoint *ap;
NMAccessPoint *found_ap = NULL;
NMAPListIter *iter;
if (!addr)
return (NULL);
if (!list)
return (NULL);
if (!(iter = nm_ap_list_iter_new (list)))
return (NULL);
while ((ap = nm_ap_list_iter_next (iter)))
{
GSList *user_addrs;
gboolean success = FALSE;
if (nm_ap_get_address (ap) && (memcmp (addr, nm_ap_get_address (ap), sizeof (struct ether_addr)) == 0))
success = TRUE;
if (!success && (user_addrs = nm_ap_get_user_addresses (ap)))
{
char char_addr[20];
GSList *elt;
memset (&char_addr[0], 0, 20);
iw_ether_ntop (addr, &char_addr[0]);
for (elt = user_addrs; elt; elt = g_slist_next (elt))
{
if (elt->data && !strcmp (elt->data, &char_addr[0]))
{
success = TRUE;
break;
}
}
g_slist_foreach (user_addrs, (GFunc)g_free, NULL);
g_slist_free (user_addrs);
}
if (success)
{
found_ap = ap;
break;
}
}
nm_ap_list_iter_free (iter);
return (found_ap);
}
/*
* nm_ap_list_copy_properties
*
* Update properties (like encryption keys or timestamps) in one access point list from
* access points in another list, if the APs in the first list are present
* in the second.
*
*/
void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *source)
{
NMAPListIter *iter;
NMAccessPoint *dest_ap;
if (!dest || !source)
return;
if (!(iter = nm_ap_list_iter_new (dest)))
return;
while ((dest_ap = nm_ap_list_iter_next (iter)))
{
NMAccessPoint *src_ap = NULL;
if ((src_ap = nm_ap_list_get_ap_by_ssid (source, nm_ap_get_ssid (dest_ap))))
{
nm_ap_set_invalid (dest_ap, nm_ap_get_invalid (src_ap));
nm_ap_set_flags (dest_ap, nm_ap_get_flags (src_ap));
nm_ap_set_wpa_flags (dest_ap, nm_ap_get_wpa_flags (src_ap));
nm_ap_set_rsn_flags (dest_ap, nm_ap_get_rsn_flags (src_ap));
nm_ap_set_timestamp_via_timestamp (dest_ap, nm_ap_get_timestamp (src_ap));
}
}
nm_ap_list_iter_free (iter);
}
/*
* nm_ap_list_copy_one_ssid_by_address
*
* If the access point doesn't have an SSID, search through a list of access points
* and find one (if any) that has the MAC address of the access point we're looking for.
* If one is found, copy the SSID over to the original access point.
*
*/
void
nm_ap_list_copy_one_ssid_by_address (NMAccessPoint *ap,
NMAccessPointList *search_list)
{
NMAccessPoint * found_ap;
const GByteArray * ssid;
g_return_if_fail (ap != NULL);
/* Ignore APs that already have an SSID */
if (!search_list || nm_ap_get_ssid (ap))
return;
found_ap = nm_ap_list_get_ap_by_address (search_list, nm_ap_get_address (ap));
ssid = found_ap ? nm_ap_get_ssid (found_ap) : NULL;
if (ssid)
nm_ap_set_ssid (ap, ssid);
}
/*
* nm_ap_list_copy_ssids_by_address
*
* For each blank-SSID access point in the destination list, try to find
* an access point in the source list that has the same MAC address, and if
* its found, copy the source access point's SSID to the dest access point.
*
*/
void
nm_ap_list_copy_ssids_by_address (NMAccessPointList *dest,
NMAccessPointList *source)
{
NMAPListIter *iter;
NMAccessPoint *dest_ap;
if (!dest || !source)
return;
if (!(iter = nm_ap_list_iter_new (dest)))
return;
while ((dest_ap = nm_ap_list_iter_next (iter)))
nm_ap_list_copy_one_ssid_by_address (dest_ap, source);
nm_ap_list_iter_free (iter);
}
/*
* nm_ap_list_get_type
*
* Return the type of an AP list
*
*/
NMNetworkType nm_ap_list_get_type (NMAccessPointList *list)
{
g_return_val_if_fail (list != NULL, NETWORK_TYPE_UNKNOWN);
return (list->type);
}
struct NMAPListIter
{
NMAccessPointList * list;
GSList * cur_pos;
gboolean valid;
};
NMAPListIter * nm_ap_list_iter_new (NMAccessPointList *list)
{
NMAPListIter *iter;
g_return_val_if_fail (list != NULL, NULL);
iter = g_slice_new (NMAPListIter);
iter->list = list;
iter->cur_pos = list->ap_list;
iter->valid = FALSE;
return iter;
}
NMAccessPoint * nm_ap_list_iter_get_ap (NMAPListIter *iter)
{
g_return_val_if_fail (iter != NULL, NULL);
g_return_val_if_fail (iter->valid, NULL);
if (!iter->cur_pos)
return (NULL);
return ((NMAccessPoint *)(iter->cur_pos->data));
}
NMAccessPoint * nm_ap_list_iter_next (NMAPListIter *iter)
{
g_return_val_if_fail (iter != NULL, NULL);
if (iter->valid) {
iter->cur_pos = g_slist_next (iter->cur_pos);
} else {
iter->valid = TRUE;
iter->cur_pos = iter->list->ap_list;
}
return (nm_ap_list_iter_get_ap (iter));
}
void nm_ap_list_iter_free (NMAPListIter *iter)
{
g_return_if_fail (iter != NULL);
memset (iter, 0, sizeof (struct NMAPListIter));
g_slice_free (NMAPListIter, iter);
}
/*
* nm_ap_list_print_members
*
* Print the information about each access point in an AP list
*
*/
void nm_ap_list_print_members (NMAccessPointList *list, const char *name)
{
NMAccessPoint * ap;
NMAPListIter * iter;
int i = 0;
g_return_if_fail (list != NULL);
g_return_if_fail (name != NULL);
if (!(iter = nm_ap_list_iter_new (list)))
return;
nm_info ("AP_LIST_PRINT: printing members of '%s'", name);
while ((ap = nm_ap_list_iter_next (iter)))
nm_ap_print_self (ap, "::\t");
nm_info ("AP_LIST_PRINT: done");
nm_ap_list_iter_free (iter);
}

View File

@@ -1,61 +0,0 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2004 Red Hat, Inc.
*/
#ifndef NETWORK_MANAGER_AP_LIST_H
#define NETWORK_MANAGER_AP_LIST_H
#include <glib.h>
#include "NetworkManager.h"
#include "NetworkManagerMain.h"
#include "NetworkManagerAP.h"
typedef struct NMAccessPointList NMAccessPointList;
typedef struct NMAPListIter NMAPListIter;
NMAccessPointList * nm_ap_list_new (NMNetworkType type);
void nm_ap_list_ref (NMAccessPointList *list);
void nm_ap_list_unref (NMAccessPointList *list);
guint nm_ap_list_size (NMAccessPointList *list);
gboolean nm_ap_list_is_empty (NMAccessPointList *list);
void nm_ap_list_append_ap (NMAccessPointList *list, NMAccessPoint *ap);
void nm_ap_list_remove_ap (NMAccessPointList *list, NMAccessPoint *ap);
void nm_ap_list_remove_ap_by_ssid (NMAccessPointList *list, const GByteArray * ssid);
void nm_ap_list_remove_duplicate_ssids (NMAccessPointList *list);
NMAccessPoint * nm_ap_list_get_ap_by_ssid (NMAccessPointList *list, const GByteArray * ssid);
NMAccessPoint * nm_ap_list_get_ap_by_address (NMAccessPointList *list, const struct ether_addr *addr);
void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *source);
void nm_ap_list_copy_ssids_by_address (NMAccessPointList *dest, NMAccessPointList *source);
void nm_ap_list_copy_one_ssid_by_address (NMAccessPoint *ap, NMAccessPointList *search_list);
NMNetworkType nm_ap_list_get_type (NMAccessPointList *list);
NMAPListIter * nm_ap_list_iter_new (NMAccessPointList *list);
NMAccessPoint * nm_ap_list_iter_get_ap (NMAPListIter *iter);
NMAccessPoint * nm_ap_list_iter_next (NMAPListIter *iter);
void nm_ap_list_iter_free (NMAPListIter *iter);
void nm_ap_list_print_members (NMAccessPointList *list, const char *name);
#endif

View File

@@ -22,13 +22,6 @@
#ifndef NETWORK_MANAGER_MAIN_H
#define NETWORK_MANAGER_MAIN_H
#include <glib.h>
#include <glib/gthread.h>
#include <dbus/dbus.h>
#include "NetworkManagerAPList.h"
#include "nm-named-manager.h"
typedef struct NMVPNActRequest NMVPNActRequest;
typedef struct NMVPNManager NMVPNManager;

View File

@@ -31,7 +31,6 @@
#include "NetworkManagerPolicy.h"
#include "NetworkManagerUtils.h"
#include "NetworkManagerAP.h"
#include "NetworkManagerAPList.h"
#include "nm-activation-request.h"
#include "nm-utils.h"
#include "nm-device-interface.h"
@@ -66,25 +65,31 @@ static NMPolicy *global_policy;
*/
static NMDevice *
nm_policy_auto_get_best_device (NMPolicy *policy,
NMConnection **connection)
NMConnection **connection,
char **specific_object)
{
GSList * elt;
NMDevice8023Ethernet * best_wired_dev = NULL;
guint best_wired_prio = 0;
NMConnection * best_wired_connection = NULL;
char * best_wired_specific_object = NULL;
NMDevice80211Wireless * best_wireless_dev = NULL;
guint best_wireless_prio = 0;
NMConnection * best_wireless_connection = NULL;
char * best_wireless_specific_object = NULL;
NMDevice * highest_priority_dev = NULL;
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (*connection == NULL, NULL);
g_return_val_if_fail (specific_object != NULL, NULL);
g_return_val_if_fail (*specific_object == NULL, NULL);
if (nm_manager_get_state (policy->manager) == NM_STATE_ASLEEP)
return NULL;
for (elt = nm_manager_get_devices (policy->manager); elt; elt = elt->next) {
NMConnection *tmp_con = NULL;
char *tmp_obj = NULL;
gboolean link_active;
guint prio = 0;
NMDevice * dev = (NMDevice *)(elt->data);
@@ -93,7 +98,7 @@ nm_policy_auto_get_best_device (NMPolicy *policy,
link_active = nm_device_has_active_link (dev);
caps = nm_device_get_capabilities (dev);
tmp_con = nm_device_get_best_connection (dev);
tmp_con = nm_device_get_best_connection (dev, &tmp_obj);
if (tmp_con == NULL)
continue;
@@ -108,6 +113,7 @@ nm_policy_auto_get_best_device (NMPolicy *policy,
best_wired_dev = NM_DEVICE_802_3_ETHERNET (dev);
best_wired_prio = prio;
best_wired_connection = tmp_con;
best_wired_specific_object = tmp_obj;
}
}
else if (NM_IS_DEVICE_802_11_WIRELESS (dev) &&
@@ -125,6 +131,7 @@ nm_policy_auto_get_best_device (NMPolicy *policy,
best_wireless_dev = NM_DEVICE_802_11_WIRELESS (dev);
best_wireless_prio = prio;
best_wireless_connection = tmp_con;
best_wireless_specific_object = tmp_obj;
}
}
}
@@ -132,6 +139,7 @@ nm_policy_auto_get_best_device (NMPolicy *policy,
if (best_wired_dev) {
highest_priority_dev = NM_DEVICE (best_wired_dev);
*connection = best_wired_connection;
*specific_object = best_wired_specific_object;
} else if (best_wireless_dev) {
gboolean can_activate;
@@ -139,6 +147,7 @@ nm_policy_auto_get_best_device (NMPolicy *policy,
if (can_activate) {
highest_priority_dev = NM_DEVICE (best_wireless_dev);
*connection = best_wireless_connection;
*specific_object = best_wireless_specific_object;
}
}
@@ -163,49 +172,6 @@ out:
return *connection ? highest_priority_dev : NULL;
}
static NMConnection *
create_connection (NMDevice *device, NMAccessPoint *ap)
{
NMConnection *connection = NULL;
NMSetting *setting = NULL;
if (NM_IS_DEVICE_802_3_ETHERNET (device)) {
nm_info ("Will activate connection '%s'.", nm_device_get_iface (device));
setting = nm_setting_wired_new ();
} else if (NM_IS_DEVICE_802_11_WIRELESS (device) && ap) {
NMSettingWireless *wireless;
const GByteArray * ssid = nm_ap_get_ssid (ap);
nm_info ("Will activate connection '%s/%s'.",
nm_device_get_iface (device),
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
setting = nm_setting_wireless_new ();
wireless = (NMSettingWireless *) setting;
wireless->ssid = g_byte_array_sized_new (ssid->len);
g_byte_array_append (wireless->ssid, ssid->data, ssid->len);
wireless->mode = g_strdup ("infrastructure");
} else {
nm_warning ("Unhandled device type '%s'", G_OBJECT_CLASS_NAME (device));
}
if (setting) {
NMSettingConnection *scon;
connection = nm_connection_new ();
nm_connection_add_setting (connection, setting);
scon = (NMSettingConnection *) nm_setting_connection_new ();
scon->name = g_strdup ("Auto");
scon->devtype = g_strdup (setting->name);
nm_connection_add_setting (connection, (NMSetting *) scon);
}
return connection;
}
/*
* nm_policy_device_change_check
*
@@ -223,6 +189,7 @@ nm_policy_device_change_check (gpointer user_data)
NMPolicy *policy = (NMPolicy *) user_data;
GSList *iter;
NMConnection * connection = NULL;
char * specific_object = NULL;
NMDevice * new_dev = NULL;
NMDevice * old_dev = NULL;
gboolean do_switch = FALSE;
@@ -266,7 +233,7 @@ nm_policy_device_change_check (gpointer user_data)
}
}
new_dev = nm_policy_auto_get_best_device (policy, &connection);
new_dev = nm_policy_auto_get_best_device (policy, &connection, &specific_object);
/* Four cases here:
*
@@ -372,7 +339,7 @@ nm_policy_device_change_check (gpointer user_data)
if (new_dev) {
nm_device_interface_activate (NM_DEVICE_INTERFACE (new_dev),
connection, NULL, FALSE);
connection, specific_object, FALSE);
}
}

View File

@@ -35,7 +35,6 @@
#include "nm-device-802-11-wireless.h"
#include "nm-device-interface.h"
#include "nm-device-private.h"
#include "NetworkManagerAPList.h"
#include "nm-utils.h"
#include "NetworkManagerUtils.h"
#include "NetworkManagerPolicy.h"
@@ -116,7 +115,7 @@ struct _NMDevice80211WirelessPrivate
double freqs[IW_MAX_FREQUENCIES];
gboolean scanning;
NMAccessPointList * ap_list;
GSList * ap_list;
GTimeVal scheduled_scan_time;
guint8 scan_interval; /* seconds */
guint pending_scan_id;
@@ -127,17 +126,12 @@ struct _NMDevice80211WirelessPrivate
guint periodic_source_id;
guint link_timeout_id;
/* Set when activating or activated */
NMAccessPoint *activation_ap;
/* Static options from driver */
guint8 we_version;
guint32 capabilities;
};
static void nm_device_802_11_wireless_ap_list_clear (NMDevice80211Wireless *self);
static void schedule_scan (NMDevice80211Wireless *self);
static void cancel_pending_scan (NMDevice80211Wireless *self);
@@ -237,7 +231,7 @@ nm_device_802_11_wireless_update_bssid (NMDevice80211Wireless *self,
nm_debug ("Roamed from BSSID %s to %s on wireless network '%s'",
old_addr,
new_addr,
nm_utils_escape_ssid (old_ssid->data, old_ssid->len));
nm_utils_escape_ssid ((const char *) old_ssid->data, old_ssid->len));
nm_ap_set_address (ap, &new_bssid);
@@ -343,10 +337,13 @@ get_wireless_capabilities (NMDevice80211Wireless *self,
{
guint32 minlen;
guint32 caps = NM_802_11_DEVICE_CAP_NONE;
const char * iface;
g_return_val_if_fail (self != NULL, NM_802_11_DEVICE_CAP_NONE);
g_return_val_if_fail (range != NULL, NM_802_11_DEVICE_CAP_NONE);
iface = nm_device_get_iface (NM_DEVICE (self));
minlen = ((char *) &range->enc_capa) - (char *) range + sizeof (range->enc_capa);
/* All drivers should support WEP by default */
@@ -369,7 +366,7 @@ get_wireless_capabilities (NMDevice80211Wireless *self,
if ( (caps & (NM_802_11_DEVICE_CAP_CIPHER_TKIP | NM_802_11_DEVICE_CAP_CIPHER_CCMP))
&& !(caps & (NM_802_11_DEVICE_CAP_WPA | NM_802_11_DEVICE_CAP_RSN))) {
nm_warning ("%s: device supports WPA ciphers but not WPA protocol; "
"WPA unavailable.");
"WPA unavailable.", iface);
caps &= ~WPA_CAPS;
}
@@ -377,7 +374,7 @@ get_wireless_capabilities (NMDevice80211Wireless *self,
if ( (caps & (NM_802_11_DEVICE_CAP_WPA | NM_802_11_DEVICE_CAP_RSN))
&& !(caps & (NM_802_11_DEVICE_CAP_CIPHER_TKIP | NM_802_11_DEVICE_CAP_CIPHER_CCMP)))
nm_warning ("%s: device supports WPA protocol but not WPA ciphers; "
"WPA unavailable.");
"WPA unavailable.", iface);
caps &= ~WPA_CAPS;
}
@@ -394,7 +391,7 @@ nm_device_802_11_wireless_init (NMDevice80211Wireless * self)
priv->dispose_has_run = FALSE;
priv->supplicant.iface_error_id = 0;
priv->scanning = FALSE;
priv->ap_list = nm_ap_list_new (NETWORK_TYPE_DEVICE);
priv->ap_list = NULL;
priv->we_version = 0;
memset (&(self->priv->hw_addr), 0, sizeof (struct ether_addr));
@@ -550,7 +547,6 @@ nm_device_802_11_periodic_update (gpointer data)
is activated and not scanning */
if (nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_ACTIVATED &&
!NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self)->scanning) {
NMAccessPoint *ap = nm_device_802_11_wireless_get_activation_ap (self);
nm_device_802_11_wireless_update_signal_strength (self, ap);
@@ -641,11 +637,6 @@ real_deactivate_quickly (NMDevice *dev)
/* Clean up stuff, don't leave the card associated */
nm_device_802_11_wireless_set_ssid (self, NULL);
nm_device_802_11_wireless_disable_encryption (self);
if (priv->activation_ap) {
g_object_unref (priv->activation_ap);
priv->activation_ap = NULL;
}
}
static void
@@ -664,43 +655,79 @@ real_check_connection (NMDevice *dev, NMConnection *connection)
return TRUE;
}
/*
* nm_device_copy_allowed_to_dev_list
*
* For devices that don't support wireless scanning, copy
* the allowed AP list to the device's ap list.
*
*/
void
nm_device_802_11_wireless_copy_allowed_to_dev_list (NMDevice80211Wireless *self,
NMAccessPointList *allowed_list)
typedef struct BestConnectionInfo {
NMDevice80211Wireless * self;
NMConnection * found;
NMAccessPoint * found_ap;
} BestConnectionInfo;
static void
find_best_connection (gpointer data, gpointer user_data)
{
NMAPListIter *iter;
NMAccessPoint *src_ap;
NMAccessPointList *dev_list;
BestConnectionInfo * info = (BestConnectionInfo *) user_data;
NMConnection *connection = NM_CONNECTION (data);
NMSettingConnection * s_con;
NMSettingWireless * s_wireless;
GSList * elt;
g_return_if_fail (self != NULL);
if (allowed_list == NULL)
if (info->found)
return;
nm_device_802_11_wireless_ap_list_clear (self);
self->priv->ap_list = nm_ap_list_new (NETWORK_TYPE_ALLOWED);
if (!(iter = nm_ap_list_iter_new (allowed_list)))
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, "connection");
if (s_con == NULL)
return;
fprintf (stderr, "%s: looking at connection %s\n", __func__, s_con->name);
if (strcmp (s_con->devtype, "802-11-wireless"))
return;
if (!s_con->autoconnect)
return;
dev_list = nm_device_802_11_wireless_ap_list_get (self);
while ((src_ap = nm_ap_list_iter_next (iter)))
s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, "802-11-wireless");
if (s_wireless == NULL)
return;
for (elt = info->self->priv->ap_list; elt; elt = g_slist_next (elt)) {
NMAccessPoint *ap = NM_AP (elt->data);
if (nm_ap_check_compatible (ap, connection)) {
/* All good; connection is usable */
info->found = connection;
info->found_ap = ap;
break;
}
}
}
static NMConnection *
real_get_best_connection (NMDevice *dev,
char **specific_object)
{
NMAccessPoint * dst_ap = nm_ap_new_from_ap (src_ap);
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev);
NMManager *manager = nm_manager_get ();
GSList *connections = NULL;
BestConnectionInfo find_info;
guint32 caps;
gboolean link_active;
nm_ap_list_append_ap (dev_list, dst_ap);
g_object_unref (dst_ap);
}
nm_ap_list_iter_free (iter);
/* System connections first */
connections = nm_manager_get_connections (manager, NM_CONNECTION_TYPE_SYSTEM);
memset (&find_info, 0, sizeof (BestConnectionInfo));
find_info.self = self;
g_slist_foreach (connections, find_best_connection, &find_info);
g_slist_free (connections);
/* Then user connections */
if (!find_info.found) {
connections = nm_manager_get_connections (manager, NM_CONNECTION_TYPE_USER);
find_info.self = self;
g_slist_foreach (connections, find_best_connection, &find_info);
g_slist_free (connections);
}
if (find_info.found)
*specific_object = (char *) nm_ap_get_dbus_path (find_info.found_ap);
return find_info.found;
}
/*
* nm_device_802_11_wireless_get_address
@@ -784,7 +811,7 @@ get_ap_blacklisted (NMAccessPoint *ap, GSList *addrs)
return blacklisted;
}
#if 0
/*
* nm_device_update_best_ap
*
@@ -871,99 +898,45 @@ nm_device_802_11_wireless_get_best_ap (NMDevice80211Wireless *self)
return best_ap;
}
#if 0
static gboolean
nm_device_802_11_wireless_set_activation_ap (NMDevice80211Wireless *self,
GByteArray *ssid,
NMAPSecurity *security)
{
NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self);
NMAccessPoint *ap = NULL;
NMAccessPointList * dev_ap_list;
nm_debug ("Forcing AP '%s'", nm_utils_escape_ssid (ssid->data, ssid->len));
/* Find the AP in our card's scan list first.
* If its not there, create an entirely new AP.
*/
dev_ap_list = nm_device_802_11_wireless_ap_list_get (self);
if (!(ap = nm_ap_list_get_ap_by_ssid (dev_ap_list, ssid))) {
/* We need security information from the user if the network they
* request isn't in our scan list.
*/
if (!security) {
nm_warning ("%s: tried to manually connect to network '%s' without "
"providing security information!", __func__,
nm_utils_escape_ssid (ssid->data, ssid->len));
return FALSE;
}
/* User chose a network we haven't seen in a scan, so create a
* "fake" access point and add it to the scan list.
*/
ap = nm_ap_new ();
nm_ap_set_ssid (ap, ssid);
nm_ap_set_artificial (ap, TRUE);
nm_ap_set_broadcast (ap, FALSE);
/* Ensure the AP has some capabilities. They will get overwritten
* with the correct ones next time the AP is seen in a scan.
*/
nm_ap_set_capabilities (ap, nm_ap_security_get_default_capabilities (security));
nm_ap_list_append_ap (dev_ap_list, ap);
g_object_unref (ap);
}
else
{
/* If the AP is in the ignore list, we have to remove it since
* the User Knows What's Best.
*/
nm_ap_list_remove_ap_by_ssid (app_data->invalid_ap_list,
nm_ap_get_ssid (ap));
/* If we didn't get any security info, make some up. */
if (!security)
security = nm_ap_security_new (nm_ap_get_capabilities (ap),
nm_ap_get_encrypted (ap));
}
g_assert (security);
nm_ap_set_security (ap, security);
nm_ap_add_capabilities_from_security (ap, security);
if (priv->activation_ap) {
g_object_unref (priv->activation_ap);
priv->activation_ap = NULL;
}
g_object_ref (ap);
priv->activation_ap = ap;
return TRUE;
}
#endif
/*
* nm_device_802_11_wireless_ap_list_clear
*
* Clears out the device's internal list of available access points.
*
*/
static void
nm_device_802_11_wireless_ap_list_clear (NMDevice80211Wireless *self)
static NMAccessPoint *
ap_list_get_ap_by_ssid (GSList *list,
const GByteArray * ssid)
{
g_return_if_fail (self != NULL);
NMAccessPoint * ap;
NMAccessPoint * found_ap = NULL;
GSList * elt;
if (!self->priv->ap_list)
return;
for (elt = list; elt; elt = g_slist_next (elt)) {
NMAccessPoint * ap = NM_AP (elt->data);
const GByteArray * ap_ssid = nm_ap_get_ssid (ap);
nm_ap_list_unref (self->priv->ap_list);
self->priv->ap_list = NULL;
if (ap_ssid && nm_utils_same_ssid (ap_ssid, ssid, TRUE))
return ap;
}
return NULL;
}
void
nm_device_802_11_wireless_ap_list_print (NMDevice80211Wireless *self)
{
GSList * elt;
int i = 0;
g_return_if_fail (NM_IS_DEVICE_802_11_WIRELESS (self));
nm_info ("AP_LIST_PRINT:");
for (elt = self->priv->ap_list; elt; elt = g_slist_next (elt), i++) {
NMAccessPoint * ap = NM_AP (elt->data);
nm_ap_print_self (ap, "::\t");
}
nm_info ("AP_LIST_PRINT: done");
}
/*
* nm_device_ap_list_get_ap_by_ssid
* nm_device_802_11_wireless_ap_list_get_ap_by_ssid
*
* Get the access point for a specific SSID
*
@@ -975,30 +948,7 @@ nm_device_802_11_wireless_ap_list_get_ap_by_ssid (NMDevice80211Wireless *self,
g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (ssid != NULL, NULL);
if (!self->priv->ap_list)
return NULL;
return nm_ap_list_get_ap_by_ssid (self->priv->ap_list, ssid);
}
/*
* nm_device_ap_list_get_ap_by_bssid
*
* Get the access point for a specific BSSID
*
*/
NMAccessPoint *
nm_device_802_11_wireless_ap_list_get_ap_by_bssid (NMDevice80211Wireless *self,
const struct ether_addr *bssid)
{
g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (bssid != NULL, NULL);
if (!self->priv->ap_list)
return NULL;
return nm_ap_list_get_ap_by_address (self->priv->ap_list, bssid);
return ap_list_get_ap_by_ssid (self->priv->ap_list, ssid);
}
@@ -1013,70 +963,33 @@ NMAccessPoint *
nm_device_802_11_wireless_ap_list_get_ap_by_obj_path (NMDevice80211Wireless *self,
const char *obj_path)
{
NMAccessPointList *ap_list;
NMAccessPoint *ap = NULL;
GSList * elt;
ap_list = nm_device_802_11_wireless_ap_list_get (self);
if (ap_list) {
NMAPListIter *list_iter;
for (elt = self->priv->ap_list; elt; elt = g_slist_next (elt)) {
NMAccessPoint *ap = NM_AP (elt->data);
if ((list_iter = nm_ap_list_iter_new (ap_list))) {
gboolean found = FALSE;
while (!found && (ap = nm_ap_list_iter_next (list_iter))) {
if (!strcmp (obj_path, nm_ap_get_dbus_path (ap)))
found = TRUE;
}
nm_ap_list_iter_free (list_iter);
if (!found)
ap = NULL;
}
}
return ap;
}
/*
* nm_device_ap_list_get
*
* Return a pointer to the AP list
*
*/
NMAccessPointList *
nm_device_802_11_wireless_ap_list_get (NMDevice80211Wireless *self)
{
g_return_val_if_fail (self != NULL, NULL);
return self->priv->ap_list;
return NULL;
}
static gboolean
impl_device_get_active_networks (NMDevice80211Wireless *device,
impl_device_get_active_networks (NMDevice80211Wireless *self,
GPtrArray **networks,
GError **err)
{
NMAccessPointList *ap_list;
GSList *elt;
*networks = g_ptr_array_new ();
ap_list = nm_device_802_11_wireless_ap_list_get (device);
if (ap_list) {
NMAPListIter *list_iter;
for (elt = self->priv->ap_list; elt; elt = g_slist_next (elt)) {
NMAccessPoint * ap = NM_AP (elt->data);
if ((list_iter = nm_ap_list_iter_new (ap_list))) {
NMAccessPoint *ap;
while ((ap = nm_ap_list_iter_next (list_iter))) {
if (nm_ap_get_ssid (ap))
g_ptr_array_add (*networks, g_strdup (nm_ap_get_dbus_path (ap)));
}
nm_ap_list_iter_free (list_iter);
}
}
return TRUE;
}
@@ -1687,59 +1600,6 @@ out:
return associated;
}
static gboolean
ap_need_secrets (NMDevice80211Wireless *self,
NMAccessPoint *ap,
NMConnection *connection,
gboolean *ask_user)
{
const GByteArray * ssid;
gboolean need_key = FALSE;
const char * iface;
const char * esc_ssid;
guint32 flags, wpa_flags, rsn_flags;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (ap != NULL, FALSE);
g_return_val_if_fail (connection != NULL, FALSE);
g_return_val_if_fail (ask_user != NULL, FALSE);
iface = nm_device_get_iface (NM_DEVICE (self));
ssid = nm_ap_get_ssid (ap);
esc_ssid = ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(null)";
flags = nm_ap_get_flags (ap);
wpa_flags = nm_ap_get_wpa_flags (ap);
rsn_flags = nm_ap_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)) {
nm_info ("Activation (%s/wireless): access point '%s' has no security, "
"no key needed.",
iface, esc_ssid);
} else {
if (nm_connection_have_secrets (connection)) {
nm_info ("Activation (%s/wireless): access point '%s' has security"
", and secrets exist. No new secrets needed.",
iface, esc_ssid ? esc_ssid : "(null)");
} else {
nm_info ("Activation (%s/wireless): access point '%s' has security,"
" but secrets are required.",
iface, esc_ssid);
need_key = TRUE;
/* FIXME: how to determine when to explicitly ask the user for
* secrets...
*/
}
}
return need_key;
}
/*
* ap_auth_enforced
*
@@ -1797,22 +1657,14 @@ ap_auth_enforced (NMAccessPoint *ap)
*
*/
static void
merge_scanned_ap (NMDevice80211Wireless *dev,
merge_scanned_ap (NMDevice80211Wireless *self,
NMAccessPoint *merge_ap)
{
NMAccessPointList * list;
NMAPListIter * iter;
NMAccessPoint * list_ap = NULL;
GSList * elt;
NMAccessPoint * found_ap = NULL;
list = nm_device_802_11_wireless_ap_list_get (dev);
g_assert (list);
iter = nm_ap_list_iter_new (list);
if (iter == NULL)
return;
while ((list_ap = nm_ap_list_iter_next (iter))) {
for (elt = self->priv->ap_list; elt; elt = g_slist_next (elt)) {
NMAccessPoint * list_ap = NM_AP (elt->data);
const GByteArray * list_ssid = nm_ap_get_ssid (list_ap);
const struct ether_addr * list_addr = nm_ap_get_address (list_ap);
int list_mode = nm_ap_get_mode (list_ap);
@@ -1848,7 +1700,6 @@ merge_scanned_ap (NMDevice80211Wireless *dev,
found_ap = list_ap;
break;
}
nm_ap_list_iter_free (iter);
if (found_ap) {
nm_ap_set_flags (found_ap, nm_ap_get_flags (merge_ap));
@@ -1864,8 +1715,10 @@ merge_scanned_ap (NMDevice80211Wireless *dev,
nm_ap_set_artificial (found_ap, FALSE);
} else {
/* New entry in the list */
nm_ap_list_append_ap (list, merge_ap);
network_added (dev, merge_ap);
// FIXME: figure out if reference counts are correct here for AP objects
g_object_ref (merge_ap);
self->priv->ap_list = g_slist_append (self->priv->ap_list, merge_ap);
network_added (self, merge_ap);
}
}
@@ -1873,52 +1726,43 @@ static void
cull_scan_list (NMDevice80211Wireless * self)
{
GTimeVal cur_time;
NMAccessPointList * ap_list;
NMAccessPoint * outdated_ap;
GSList * outdated_list = NULL;
GSList * elt;
NMAccessPoint * cur_ap = NULL;
NMAPListIter * iter = NULL;
g_return_if_fail (self != NULL);
g_get_current_time (&cur_time);
if (!(ap_list = nm_device_802_11_wireless_ap_list_get (self)))
return;
if (!(iter = nm_ap_list_iter_new (ap_list)))
return;
/* Walk the access point list and remove any access points older than
* thrice the inactive scan interval.
* three times the inactive scan interval.
*/
while ((outdated_ap = nm_ap_list_iter_next (iter))) {
for (elt = self->priv->ap_list; elt; elt = g_slist_next (elt)) {
NMAccessPoint * outdated_ap = NM_AP (elt->data);
const glong ap_time = nm_ap_get_last_seen (outdated_ap);
gboolean keep_around = FALSE;
guint prune_interval_s;
guint prune_interval_s = SCAN_INTERVAL_MAX * 3;
const GByteArray * ssid;
const GByteArray * cur_ssid;
/* Don't ever prune the AP we're currently associated with */
ssid = nm_ap_get_ssid (outdated_ap);
// FIXME: get cur_ap somehow
cur_ssid = cur_ap ? nm_ap_get_ssid (cur_ap) : NULL;
if (ssid && nm_utils_same_ssid (cur_ssid, ssid, TRUE))
keep_around = TRUE;
prune_interval_s = SCAN_INTERVAL_MAX * 3;
if (!keep_around && (ap_time + prune_interval_s < cur_time.tv_sec))
outdated_list = g_slist_append (outdated_list, outdated_ap);
}
nm_ap_list_iter_free (iter);
/* Remove outdated APs */
for (elt = outdated_list; elt; elt = g_slist_next (elt)) {
if (!(outdated_ap = (NMAccessPoint *)(elt->data)))
continue;
outdated_ap = NM_AP (elt->data);
network_removed (self, outdated_ap);
nm_ap_list_remove_ap (nm_device_802_11_wireless_ap_list_get (self), outdated_ap);
self->priv->ap_list = g_slist_remove (self->priv->ap_list, outdated_ap);
g_object_unref (outdated_ap);
}
g_slist_free (outdated_list);
}
@@ -2590,21 +2434,14 @@ static NMActStageReturn
real_act_stage1_prepare (NMDevice *dev)
{
NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (dev);
NMActRequest *req;
NMSettingWireless *setting;
gboolean success;
NMAccessPoint *ap;
req = nm_device_get_act_request (dev);
setting = (NMSettingWireless *) nm_connection_get_setting (nm_act_request_get_connection (req),
"802-11-wireless");
g_assert (setting);
#if 0
success = nm_device_802_11_wireless_set_activation_ap (self, setting->ssid, NULL);
#endif
/* FIXME: match up 802-11-wireless and 802-11-wireless-security to an AP */
success = NM_ACT_STAGE_RETURN_SUCCESS;
/* Make sure we've got an AP to connect to */
ap = nm_device_802_11_wireless_get_activation_ap (self);
if (!ap)
return NM_ACT_STAGE_RETURN_FAILURE;
return success ? NM_ACT_STAGE_RETURN_SUCCESS : NM_ACT_STAGE_RETURN_FAILURE;
return NM_ACT_STAGE_RETURN_SUCCESS;
}
@@ -2615,28 +2452,36 @@ real_act_stage2_config (NMDevice *dev)
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
const char * iface = nm_device_get_iface (dev);
gboolean ask_user = FALSE;
NMAccessPoint * ap;
NMSupplicantConfig * config = NULL;
gulong id = 0;
NMActRequest * req;
NMConnection * connection;
NMSettingConnection * s_connection;
remove_supplicant_timeouts (self);
ap = nm_device_802_11_wireless_get_activation_ap (self);
g_assert (ap);
req = nm_device_get_act_request (dev);
g_assert (req);
connection = nm_act_request_get_connection (req);
g_assert (connection);
s_connection = (NMSettingConnection *) nm_connection_get_setting (connection, "connection");
g_assert (s_connection);
/* If we need secrets, get them */
if (ap_need_secrets (self, ap, connection, &ask_user)) {
if (nm_connection_need_secrets (connection)) {
nm_info ("Activation (%s/wireless): access point '%s' has security,"
" but secrets are required.",
iface, s_connection->name);
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH);
// FIXME: get secrets from info-daemon
return NM_ACT_STAGE_RETURN_POSTPONE;
} else {
nm_info ("Activation (%s/wireless): connection '%s' has security"
", and secrets exist. No new secrets needed.",
iface, s_connection->name);
}
config = build_supplicant_config (self);
@@ -2805,11 +2650,9 @@ activation_success_handler (NMDevice *dev)
automatic = !nm_act_request_get_user_requested (nm_device_get_act_request (dev));
/* If it's a user-created ad-hoc network, add it to the device's scan list */
if (!automatic && (nm_ap_get_mode (ap) == IW_MODE_ADHOC) && nm_ap_get_user_created (ap))
{
NMAccessPointList *ap_list = nm_device_802_11_wireless_ap_list_get (self);
if (!nm_ap_list_get_ap_by_ssid (ap_list, nm_ap_get_ssid (ap)))
nm_ap_list_append_ap (ap_list, ap);
if (!automatic && (nm_ap_get_mode (ap) == IW_MODE_ADHOC) && nm_ap_get_user_created (ap)) {
if (!ap_list_get_ap_by_ssid (self->priv->ap_list, nm_ap_get_ssid (ap)))
self->priv->ap_list = g_slist_append (self->priv->ap_list, ap);
}
nm_device_802_11_wireless_get_bssid (self, &addr);
@@ -2827,23 +2670,17 @@ activation_failure_handler (NMDevice *dev)
NMAccessPoint * ap;
const GByteArray * ssid;
if ((ap = nm_device_802_11_wireless_get_activation_ap (self)))
{
if (nm_ap_get_artificial (ap))
{
NMAccessPointList * dev_list;
if ((ap = nm_device_802_11_wireless_get_activation_ap (self))) {
if (nm_ap_get_artificial (ap)) {
/* Artificial APs are ones that don't show up in scans,
* but which the user explicitly attempted to connect to.
* However, if we fail on one of these, remove it from the
* list because we don't have any scan or capability info
* for it, and they are pretty much useless.
*/
dev_list = nm_device_802_11_wireless_ap_list_get (self);
nm_ap_list_remove_ap (dev_list, ap);
}
else
{
self->priv->ap_list = g_slist_remove (self->priv->ap_list, ap);
g_object_unref (ap);
} else {
/* Add the AP to the invalid list */
nm_ap_set_invalid (ap, TRUE);
}
@@ -2895,6 +2732,7 @@ nm_device_802_11_wireless_dispose (GObject *object)
{
NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (object);
NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self);
GSList * elt;
/* Make sure dispose does not run twice. */
if (priv->dispose_has_run)
@@ -2903,9 +2741,9 @@ nm_device_802_11_wireless_dispose (GObject *object)
priv->dispose_has_run = TRUE;
/* General cleanup, free references to other objects */
nm_device_802_11_wireless_ap_list_clear (self);
if (priv->ap_list)
nm_ap_list_unref (priv->ap_list);
g_slist_foreach (self->priv->ap_list, (GFunc) g_object_unref, NULL);
g_slist_free (self->priv->ap_list);
self->priv->ap_list = NULL;
device_cleanup (self);
@@ -2918,6 +2756,7 @@ get_property (GObject *object, guint prop_id,
{
NMDevice80211Wireless *device = NM_DEVICE_802_11_WIRELESS (object);
NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (device);
NMAccessPoint *ap;
struct ether_addr hw_addr;
char hw_addr_buf[20];
@@ -2938,8 +2777,8 @@ get_property (GObject *object, guint prop_id,
g_value_set_uint (value, priv->capabilities);
break;
case PROP_ACTIVE_NETWORK:
if (priv->activation_ap)
g_value_set_object (value, priv->activation_ap);
if ((ap = nm_device_802_11_wireless_get_activation_ap (device)))
g_value_set_object (value, ap);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -2967,6 +2806,7 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *klass)
parent_class->update_link = real_update_link;
parent_class->set_hw_address = real_set_hw_address;
parent_class->check_connection = real_check_connection;
parent_class->get_best_connection = real_get_best_connection;
parent_class->act_stage1_prepare = real_act_stage1_prepare;
parent_class->act_stage2_config = real_act_stage2_config;
@@ -3056,11 +2896,8 @@ state_changed_cb (NMDevice *device, NMDeviceState state, gpointer user_data)
activation_failure_handler (device);
break;
case NM_DEVICE_STATE_DISCONNECTED:
if (priv->activation_ap) {
nm_info ("%s(): clearing activation AP", __func__);
g_object_unref (priv->activation_ap);
priv->activation_ap = NULL;
}
// FIXME: ensure that the activation request is destroyed
break;
default:
break;
}
@@ -3098,8 +2935,19 @@ nm_device_802_11_wireless_new (int index,
NMAccessPoint *
nm_device_802_11_wireless_get_activation_ap (NMDevice80211Wireless *self)
{
NMActRequest *req;
const char *ap_path;
g_return_val_if_fail (NM_IS_DEVICE_802_11_WIRELESS (self), NULL);
return NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self)->activation_ap;
req = nm_device_get_act_request (NM_DEVICE (self));
if (!req)
return NULL;
ap_path = nm_act_request_get_specific_object (req);
if (!ap_path)
return NULL;
return nm_device_802_11_wireless_ap_list_get_ap_by_obj_path (self, ap_path);
}

View File

@@ -98,21 +98,11 @@ gboolean nm_device_802_11_wireless_set_mode (NMDevice80211Wireless *self,
int nm_device_802_11_wireless_get_bitrate (NMDevice80211Wireless *self);
NMAccessPoint * nm_device_802_11_wireless_get_best_ap (NMDevice80211Wireless *dev);
NMAccessPoint * nm_device_802_11_wireless_get_activation_ap (NMDevice80211Wireless *dev);
void nm_device_802_11_wireless_reset_scan_interval (NMDevice80211Wireless *dev);
void nm_device_802_11_wireless_copy_allowed_to_dev_list (NMDevice80211Wireless *self,
struct NMAccessPointList *allowed_list);
struct NMAccessPointList * nm_device_802_11_wireless_ap_list_get (NMDevice80211Wireless *dev);
NMAccessPoint * nm_device_802_11_wireless_ap_list_get_ap_by_obj_path (NMDevice80211Wireless *dev,
const char *obj_path);
NMAccessPoint * nm_device_802_11_wireless_ap_list_get_ap_by_bssid (NMDevice80211Wireless *dev,
const struct ether_addr *bssid);
NMAccessPoint * nm_device_802_11_wireless_ap_list_get_ap_by_ssid (NMDevice80211Wireless *dev,
const GByteArray * ssid);
@@ -120,6 +110,8 @@ int nm_device_802_11_wireless_get_mode (NMDevice80211Wireless *self);
gboolean nm_device_802_11_wireless_can_activate (NMDevice80211Wireless * self);
NMAccessPoint * nm_device_802_11_wireless_get_activation_ap (NMDevice80211Wireless *self);
G_END_DECLS

View File

@@ -377,7 +377,8 @@ find_best_connection (gpointer data, gpointer user_data)
}
static NMConnection *
real_get_best_connection (NMDevice *dev)
real_get_best_connection (NMDevice *dev,
char **specific_object)
{
NMDevice8023Ethernet * self = NM_DEVICE_802_3_ETHERNET (dev);
NMManager *manager = nm_manager_get ();

View File

@@ -381,11 +381,14 @@ nm_device_set_active_link (NMDevice *self,
NMConnection *
nm_device_get_best_connection (NMDevice *dev)
nm_device_get_best_connection (NMDevice *dev,
char **specific_object)
{
guint32 caps;
g_return_val_if_fail (NM_IS_DEVICE (dev), NULL);
g_return_val_if_fail (specific_object != NULL, NULL);
g_return_val_if_fail (*specific_object == NULL, NULL);
caps = nm_device_get_capabilities (dev);
/* Don't use devices that SUCK */
@@ -395,7 +398,7 @@ nm_device_get_best_connection (NMDevice *dev)
if (!NM_DEVICE_GET_CLASS (dev)->get_best_connection)
return NULL;
return NM_DEVICE_GET_CLASS (dev)->get_best_connection (dev);
return NM_DEVICE_GET_CLASS (dev)->get_best_connection (dev, specific_object);
}
/*

View File

@@ -90,7 +90,8 @@ struct _NMDeviceClass
guint32 (* get_type_capabilities) (NMDevice *self);
guint32 (* get_generic_capabilities) (NMDevice *self);
NMConnection * (* get_best_connection) (NMDevice *self);
NMConnection * (* get_best_connection) (NMDevice *self,
char **specific_object);
gboolean (* check_connection) (NMDevice *self, NMConnection *connection);
@@ -144,7 +145,8 @@ void * nm_device_get_system_config_data (NMDevice *dev);
NMActRequest * nm_device_get_act_request (NMDevice *dev);
NMConnection * nm_device_get_best_connection (NMDevice *dev);
NMConnection * nm_device_get_best_connection (NMDevice *dev,
char **specific_object);
void nm_device_activate_schedule_stage1_device_prepare (NMDevice *device);
void nm_device_activate_schedule_stage2_device_config (NMDevice *device);