From 75478a37684fcf95d630428af903fd07c70bceef Mon Sep 17 00:00:00 2001 From: Robert Love Date: Thu, 8 Jun 2006 21:01:37 +0000 Subject: [PATCH] 2006-06-08 Robert Love Add 'fallback' support. NetworkManager will attempt to brute-force connect to networks marked as fallback if there are no better wireless connections available. This is useful as a method of last resort, to work around driver problems, and for use with hidden networks. * gnome/applet/applet-dbus-devices.c, gnome/applet/applet-dbus-devices.h: Add fallback parameter. * gnome/applet/applet-dbus-info.c: Retrieve fallback bit from Gconf and pass it on via DBUS. * gnome/applet/applet.c: No fallback by default. * gnome/applet/applet.glade, gnome/applet/other-network-dialog.c: Update other-network-dialog to add UI checkbox toggling fallback. * src/NetworkManagerAP.c, src/NetworkManagerAP.h: Remove "trusted" propery from AP object. Add "fallback" property to AP object. * src/nm-dbus-nm.c: Grab the fallback parameter via DBUS. * src/nm-dbus-nmi.c: Grab the fallback parameter via DBUS. * src/nm-device-802-11-wireless.c: Break out blacklist logic into separate function. Add get_best_fallback_ap() for returning an AP on which to attempt fallback. * src/backends/NetworkManagerSuSE.c: Set stored network as fallback. * test/nm-set-fallback: New file. Sets a given network as fallback. git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1814 4912f4e0-d625-0410-9fb7-b9a5a253dbdc --- ChangeLog | 23 ++++ gnome/applet/applet-dbus-devices.c | 3 +- gnome/applet/applet-dbus-devices.h | 2 +- gnome/applet/applet-dbus-info.c | 30 +++-- gnome/applet/applet.c | 2 +- gnome/applet/applet.glade | 36 ++++-- gnome/applet/other-network-dialog.c | 7 +- src/NetworkManagerAP.c | 12 +- src/NetworkManagerAP.h | 4 +- src/backends/NetworkManagerSuSE.c | 4 +- src/nm-dbus-nm.c | 11 ++ src/nm-dbus-nmi.c | 22 ++-- src/nm-device-802-11-wireless.c | 167 ++++++++++++++++++++-------- test/nm-set-fallback | 27 +++++ 14 files changed, 265 insertions(+), 85 deletions(-) create mode 100644 test/nm-set-fallback diff --git a/ChangeLog b/ChangeLog index 445ec3775a..c7cafd028e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2006-06-08 Robert Love + + Add 'fallback' support. NetworkManager will attempt to brute-force + connect to networks marked as fallback if there are no better wireless + connections available. This is useful as a method of last resort, to + work around driver problems, and for use with hidden networks. + * gnome/applet/applet-dbus-devices.c, + gnome/applet/applet-dbus-devices.h: Add fallback parameter. + * gnome/applet/applet-dbus-info.c: Retrieve fallback bit from Gconf and + pass it on via DBUS. + * gnome/applet/applet.c: No fallback by default. + * gnome/applet/applet.glade, gnome/applet/other-network-dialog.c: + Update other-network-dialog to add UI checkbox toggling fallback. + * src/NetworkManagerAP.c, src/NetworkManagerAP.h: Remove "trusted" + propery from AP object. Add "fallback" property to AP object. + * src/nm-dbus-nm.c: Grab the fallback parameter via DBUS. + * src/nm-dbus-nmi.c: Grab the fallback parameter via DBUS. + * src/nm-device-802-11-wireless.c: Break out blacklist logic into + separate function. Add get_best_fallback_ap() for returning an AP + on which to attempt fallback. + * src/backends/NetworkManagerSuSE.c: Set stored network as fallback. + * test/nm-set-fallback: New file. Sets a given network as fallback. + 2006-06-07 Robert Love * gnome/applet/gconf-helpers.c: Bug fix: nm_gconf_helper_get_bool() diff --git a/gnome/applet/applet-dbus-devices.c b/gnome/applet/applet-dbus-devices.c index e14828ca3d..65aec24f6d 100644 --- a/gnome/applet/applet-dbus-devices.c +++ b/gnome/applet/applet-dbus-devices.c @@ -1275,7 +1275,7 @@ void nma_dbus_device_remove_one_device (NMApplet *applet, const char *dev_path) * */ void nma_dbus_set_device (DBusConnection *connection, NetworkDevice *dev, const char *essid, - WirelessSecurityOption * opt) + gboolean fallback, WirelessSecurityOption * opt) { DBusMessage * message; gboolean success = TRUE; @@ -1294,6 +1294,7 @@ void nma_dbus_set_device (DBusConnection *connection, NetworkDevice *dev, const /* Build up the required args */ dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_STRING, &essid, + DBUS_TYPE_BOOLEAN, &fallback, DBUS_TYPE_INVALID); /* If we have specific wireless security options, add them */ diff --git a/gnome/applet/applet-dbus-devices.h b/gnome/applet/applet-dbus-devices.h index 05562af299..13183e4698 100644 --- a/gnome/applet/applet-dbus-devices.h +++ b/gnome/applet/applet-dbus-devices.h @@ -49,7 +49,7 @@ void nma_dbus_device_remove_one_device (NMApplet *applet, const char *dev_pa void nma_dbus_device_update_one_network (NMApplet *applet, const char *dev_path, const char *net_path, const char *active_net_path); void nma_dbus_device_remove_one_network (NMApplet *applet, const char *dev_path, const char *net_path); void nma_dbus_update_strength (NMApplet *applet, const char *dev_path, const char *net_path, int strength); -void nma_dbus_set_device (DBusConnection *connection, NetworkDevice *dev, const char *essid, WirelessSecurityOption *opt); +void nma_dbus_set_device (DBusConnection *connection, NetworkDevice *dev, const char *essid, gboolean fallback, WirelessSecurityOption *opt); void nma_dbus_create_network (DBusConnection *connection, NetworkDevice *dev, const char *essid, WirelessSecurityOption *opt); void nma_free_data_model (NMApplet *applet); diff --git a/gnome/applet/applet-dbus-info.c b/gnome/applet/applet-dbus-info.c index 5789047366..897e1b7f53 100644 --- a/gnome/applet/applet-dbus-info.c +++ b/gnome/applet/applet-dbus-info.c @@ -395,7 +395,7 @@ nmi_dbus_get_network_properties (DBusConnection *connection, char * escaped_network = NULL; char * essid = NULL; gint timestamp = -1; - gboolean trusted = FALSE; + gboolean fallback = FALSE; DBusMessageIter iter, array_iter; GConfClient * client; NMGConfWSO * gconf_wso; @@ -435,9 +435,9 @@ nmi_dbus_get_network_properties (DBusConnection *connection, if (!nm_gconf_get_int_helper (client, GCONF_PATH_WIRELESS_NETWORKS, "timestamp", escaped_network, ×tamp) || (timestamp < 0)) timestamp = 0; - /* Trusted status */ - if (!nm_gconf_get_bool_helper (client, GCONF_PATH_WIRELESS_NETWORKS, "trusted", escaped_network, &trusted)) - trusted = FALSE; + /* Fallback status */ + if (!nm_gconf_get_bool_helper (client, GCONF_PATH_WIRELESS_NETWORKS, "fallback", escaped_network, &fallback)) + fallback = FALSE; /* Grab the list of stored access point BSSIDs */ gconf_key = g_strdup_printf ("%s/%s/bssids", GCONF_PATH_WIRELESS_NETWORKS, escaped_network); @@ -468,8 +468,8 @@ nmi_dbus_get_network_properties (DBusConnection *connection, /* Second arg: Timestamp (INT32) */ dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, ×tamp); - /* Third arg: Trusted (BOOLEAN) */ - dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &trusted); + /* Third arg: Fallback? (BOOLEAN) */ + dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &fallback); /* Fourth arg: List of AP BSSIDs (ARRAY, STRING) */ dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &array_iter); @@ -818,6 +818,7 @@ static void nmi_save_network_info (NMApplet *applet, const char *essid, gboolean automatic, + gboolean fallback, const char *bssid, NMGConfWSO * gconf_wso) { @@ -856,6 +857,10 @@ nmi_save_network_info (NMApplet *applet, g_free (key); } + key = g_strdup_printf ("%s/%s/fallback", GCONF_PATH_WIRELESS_NETWORKS, escaped_network); + gconf_client_set_bool (applet->gconf_client, key, fallback, NULL); + g_free (key); + if (bssid && (strlen (bssid) >= 11)) { GConfValue * value; @@ -954,6 +959,7 @@ nmi_dbus_update_network_info (DBusConnection *connection, NMApplet * applet = (NMApplet *) user_data; char * essid = NULL; gboolean automatic; + gboolean fallback; NMGConfWSO * gconf_wso = NULL; DBusMessageIter iter; char * bssid; @@ -984,7 +990,15 @@ nmi_dbus_update_network_info (DBusConnection *connection, } dbus_message_iter_get_basic (&iter, &automatic); - /* Third argument: Access point's BSSID */ + /* Third argument: Fallback? (BOOLEAN) */ + if (!dbus_message_iter_next (&iter) || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN)) + { + nm_warning ("%s:%d - message argument 'fallback' was invalid.", __FILE__, __LINE__); + goto out; + } + dbus_message_iter_get_basic (&iter, &fallback); + + /* Fourth argument: Access point's BSSID */ if (!dbus_message_iter_next (&iter) || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)) { nm_warning ("%s:%d - message argument 'bssid' was invalid.", __FILE__, __LINE__); @@ -1002,7 +1016,7 @@ nmi_dbus_update_network_info (DBusConnection *connection, goto out; } - nmi_save_network_info (applet, essid, automatic, bssid, gconf_wso); + nmi_save_network_info (applet, essid, automatic, fallback, bssid, gconf_wso); g_object_unref (G_OBJECT (gconf_wso)); out: diff --git a/gnome/applet/applet.c b/gnome/applet/applet.c index 221216d063..d5f86d21bb 100644 --- a/gnome/applet/applet.c +++ b/gnome/applet/applet.c @@ -1287,7 +1287,7 @@ static void nma_menu_item_activate (GtkMenuItem *item, gpointer user_data) if ((tag = g_object_get_data (G_OBJECT (item), "network"))) net = network_device_get_wireless_network_by_essid (dev, tag); - nma_dbus_set_device (applet->connection, dev, net ? wireless_network_get_essid (net) : NULL, NULL); + nma_dbus_set_device (applet->connection, dev, net ? wireless_network_get_essid (net) : NULL, FALSE, NULL); network_device_unref (dev); nmi_dbus_signal_user_interface_activated (applet->connection); diff --git a/gnome/applet/applet.glade b/gnome/applet/applet.glade index d902070454..eb3e443287 100644 --- a/gnome/applet/applet.glade +++ b/gnome/applet/applet.glade @@ -426,7 +426,7 @@ You have chosen to log in to the wireless network '%s'. If you are sure that th True - 4 + 5 2 False 6 @@ -548,8 +548,8 @@ You have chosen to log in to the wireless network '%s'. If you are sure that th 0 1 - 2 - 3 + 3 + 4 fill @@ -569,8 +569,8 @@ WEP 64/128-bit ASCII 1 2 - 2 - 3 + 3 + 4 fill fill @@ -589,11 +589,33 @@ WEP 64/128-bit ASCII 0 2 - 3 - 4 + 4 + 5 fill + + + + True + True + _Fallback on this Network + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 1 + 2 + 2 + 3 + fill + + + 0 diff --git a/gnome/applet/other-network-dialog.c b/gnome/applet/other-network-dialog.c index 4669cf168c..01f6e6d91b 100644 --- a/gnome/applet/other-network-dialog.c +++ b/gnome/applet/other-network-dialog.c @@ -410,19 +410,24 @@ static void nma_ond_response_cb (GtkDialog *dialog, gint response, gpointer data WirelessSecurityOption * opt; GtkComboBox * security_combo; GtkTreeIter iter; + GtkWidget * fallback_button; char * str; NetworkDevice * dev; + gboolean fallback; gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter); gtk_tree_model_get (model, &iter, NAME_COLUMN, &str, DEV_COLUMN, &dev, -1); + fallback_button = glade_xml_get_widget (xml, "fallback_button"); + fallback = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fallback_button)); + security_combo = GTK_COMBO_BOX (glade_xml_get_widget (xml, "security_combo")); opt = wsm_get_option_for_active (wsm, security_combo); if (create_network) nma_dbus_create_network (applet->connection, dev, essid, opt); else - nma_dbus_set_device (applet->connection, dev, essid, opt); + nma_dbus_set_device (applet->connection, dev, essid, fallback, opt); } } diff --git a/src/NetworkManagerAP.c b/src/NetworkManagerAP.c index 6d3c749c19..0660e0379e 100644 --- a/src/NetworkManagerAP.c +++ b/src/NetworkManagerAP.c @@ -51,7 +51,7 @@ struct NMAccessPoint GTimeVal last_seen; /* Last time the AP was seen in a scan */ /* Things from user prefs/NetworkManagerInfo */ - gboolean trusted; + gboolean fallback; NMAPSecurity * security; GTimeVal timestamp; GSList * user_addresses; @@ -398,21 +398,21 @@ void nm_ap_set_invalid (NMAccessPoint *ap, gboolean invalid) /* * Get/Set functions to indicate that an access point is - * 'trusted' + * 'fallback' * */ -gboolean nm_ap_get_trusted (const NMAccessPoint *ap) +gboolean nm_ap_get_fallback (const NMAccessPoint *ap) { g_return_val_if_fail (ap != NULL, FALSE); - return (ap->trusted); + return (ap->fallback); } -void nm_ap_set_trusted (NMAccessPoint *ap, gboolean trusted) +void nm_ap_set_fallback (NMAccessPoint *ap, gboolean fallback) { g_return_if_fail (ap != NULL); - ap->trusted = trusted; + ap->fallback = fallback; } diff --git a/src/NetworkManagerAP.h b/src/NetworkManagerAP.h index fc376ba3e6..dd2135eb12 100644 --- a/src/NetworkManagerAP.h +++ b/src/NetworkManagerAP.h @@ -72,8 +72,8 @@ void nm_ap_set_rate (NMAccessPoint *ap, guint16 rate); gboolean nm_ap_get_invalid (const NMAccessPoint *ap); void nm_ap_set_invalid (NMAccessPoint *ap, gboolean invalid); -gboolean nm_ap_get_trusted (const NMAccessPoint *ap); -void nm_ap_set_trusted (NMAccessPoint *ap, gboolean trusted); +gboolean nm_ap_get_fallback (const NMAccessPoint *ap); +void nm_ap_set_fallback (NMAccessPoint *ap, gboolean fallback); gboolean nm_ap_get_artificial (const NMAccessPoint *ap); void nm_ap_set_artificial (NMAccessPoint *ap, gboolean artificial); diff --git a/src/backends/NetworkManagerSuSE.c b/src/backends/NetworkManagerSuSE.c index 1bad8a626e..544954236e 100644 --- a/src/backends/NetworkManagerSuSE.c +++ b/src/backends/NetworkManagerSuSE.c @@ -543,7 +543,7 @@ found: ap = nm_ap_new (); nm_ap_set_essid (ap, buf); nm_ap_set_timestamp (ap, time (NULL), 0); - nm_ap_set_trusted (ap, TRUE); + nm_ap_set_fallback (ap, TRUE); if ((mode = svGetValue (file, "WIRELESS_AUTH_MODE")) && !strcmp (mode, "psk")) { @@ -644,7 +644,7 @@ found: { nm_ap_set_essid (list_ap, nm_ap_get_essid (ap)); nm_ap_set_timestamp_via_timestamp (list_ap, nm_ap_get_timestamp (ap)); - nm_ap_set_trusted (list_ap, nm_ap_get_trusted (ap)); + nm_ap_set_fallback (list_ap, TRUE); nm_ap_set_security (list_ap, nm_ap_get_security (ap)); } else diff --git a/src/nm-dbus-nm.c b/src/nm-dbus-nm.c index 89af143c1b..64b33b46ac 100644 --- a/src/nm-dbus-nm.c +++ b/src/nm-dbus-nm.c @@ -261,6 +261,7 @@ static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DB { NMAPSecurity * security = NULL; char * essid = NULL; + gboolean fallback = FALSE; if (!dbus_message_iter_next (&iter) || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)) { @@ -276,6 +277,15 @@ static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DB goto out; } + if (!dbus_message_iter_next (&iter) || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN)) + { + nm_warning ("Invalid argument type (fallback"); + goto out; + } + + /* grab the fallback bit */ + dbus_message_iter_get_basic (&iter, &fallback); + /* If there's security information, we use that. If not, we * make some up from the scan list. */ @@ -292,6 +302,7 @@ static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DB /* Set up the wireless-specific activation request properties */ ap = nm_device_802_11_wireless_get_activation_ap (NM_DEVICE_802_11_WIRELESS (dev), essid, security); + nm_ap_set_fallback (ap, fallback); if (security) g_object_unref (G_OBJECT (security)); diff --git a/src/nm-dbus-nmi.c b/src/nm-dbus-nmi.c index 6be71ecc8d..083cf6f8d9 100644 --- a/src/nm-dbus-nmi.c +++ b/src/nm-dbus-nmi.c @@ -224,6 +224,7 @@ gboolean nm_dbus_update_network_info (DBusConnection *connection, NMAccessPoint { DBusMessage * message; gboolean success = FALSE; + gboolean fallback; const char * essid; gchar * char_bssid; NMAPSecurity * security; @@ -246,10 +247,14 @@ gboolean nm_dbus_update_network_info (DBusConnection *connection, NMAccessPoint /* First argument: ESSID (STRING) */ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &essid); - /* Second argument: Automatic (BOOLEAN) */ + /* Second argument: Automatic or user-driven connection? (BOOLEAN) */ dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &automatic); - /* Third argument: Access point's BSSID */ + /* Third argument: Fallback? (BOOLEAN) */ + fallback = nm_ap_get_fallback (ap); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &fallback); + + /* Fourth argument: Access point's BSSID */ addr = nm_ap_get_address (ap); if ((nm_ap_get_mode (ap) == IW_MODE_INFRA) && nm_ethernet_address_is_valid (addr)) { @@ -340,7 +345,7 @@ static void nm_dbus_get_network_data_cb (DBusPendingCall *pcall, void *user_data DBusMessageIter subiter; const char * essid = NULL; gint timestamp_secs = -1; - gboolean trusted = FALSE; + gboolean fallback = FALSE; GSList * addr_list = NULL; NMAPSecurity * security; NMAccessPoint * ap; @@ -393,14 +398,14 @@ static void nm_dbus_get_network_data_cb (DBusPendingCall *pcall, void *user_data } dbus_message_iter_get_basic (&iter, ×tamp_secs); - /* Third arg: Trusted (BOOLEAN) */ + /* Third arg: Fallback? (BOOLEAN) */ if (!dbus_message_iter_next (&iter) || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN)) { - nm_warning ("a message argument (trusted) was invalid."); + nm_warning ("a message argument (fallback) was invalid."); goto out; } - dbus_message_iter_get_basic (&iter, &trusted); + dbus_message_iter_get_basic (&iter, &fallback); /* Fourth arg: BSSID addresses (ARRAY, STRING) */ if (!dbus_message_iter_next (&iter) @@ -439,18 +444,19 @@ static void nm_dbus_get_network_data_cb (DBusPendingCall *pcall, void *user_data ap = nm_ap_new (); nm_ap_set_essid (ap, essid); nm_ap_set_security (ap, security); + nm_ap_add_capabilities_from_security (ap, security); g_object_unref (G_OBJECT (security)); /* set_security copies the object */ nm_ap_set_timestamp (ap, timestamp_secs, 0); - nm_ap_set_trusted (ap, trusted); + nm_ap_set_fallback (ap, fallback); nm_ap_set_user_addresses (ap, addr_list); if ((list_ap = nm_ap_list_get_ap_by_essid (cb_data->list, essid))) { nm_ap_set_essid (list_ap, nm_ap_get_essid (ap)); nm_ap_set_timestamp_via_timestamp (list_ap, nm_ap_get_timestamp (ap)); - nm_ap_set_trusted (list_ap, nm_ap_get_trusted (ap)); + nm_ap_set_fallback (list_ap, nm_ap_get_fallback (ap)); nm_ap_set_security (list_ap, nm_ap_get_security (ap)); nm_ap_set_user_addresses (list_ap, nm_ap_get_user_addresses (ap)); } diff --git a/src/nm-device-802-11-wireless.c b/src/nm-device-802-11-wireless.c index 628a302dca..3defcb483c 100644 --- a/src/nm-device-802-11-wireless.c +++ b/src/nm-device-802-11-wireless.c @@ -767,6 +767,103 @@ link_to_specific_ap (NMDevice80211Wireless *self, } +static gboolean +get_ap_blacklisted (NMAccessPoint *ap, GSList *addrs) +{ + gboolean blacklisted; + + blacklisted = nm_ap_has_manufacturer_default_essid (ap); + if (blacklisted) + { + GSList *elt; + const struct ether_addr *ap_addr; + char char_addr[20]; + + ap_addr = nm_ap_get_address (ap); + + memset (&char_addr[0], 0, 20); + iw_ether_ntop (ap_addr, &char_addr[0]); + + for (elt = addrs; elt; elt = g_slist_next (elt)) + { + if (elt->data && !strcmp (elt->data, &char_addr[0])) + { + blacklisted = FALSE; + break; + } + } + } + + return blacklisted; +} + + +/* + * get_best_fallback_ap + * + * Find and return the most suitable "fallback" network, if any. We "fall back" + * on these networks and attempt a brute-force connection, given no better options. + */ +static NMAccessPoint * +get_best_fallback_ap (NMDevice80211Wireless *self) +{ + NMAccessPointList * allowed_list; + NMAccessPoint * best_ap = NULL; + NMAccessPoint * allowed_ap; + GTimeVal best_timestamp = {0, 0}; + NMAPListIter * iter; + NMData * app_data; + + app_data = nm_device_get_app_data (NM_DEVICE (self)); + allowed_list = app_data->allowed_ap_list; + + iter = nm_ap_list_iter_new (allowed_list); + if (!iter) + return NULL; + + while ((allowed_ap = nm_ap_list_iter_next (iter))) + { + const char * essid; + GSList * user_addrs; + const GTimeVal * curtime; + gboolean blacklisted; + + /* Only designated fallback networks, natch */ + if (!nm_ap_get_fallback (allowed_ap)) + continue; + + /* Only connect to a blacklisted AP if the user has connected to this specific AP before */ + user_addrs = nm_ap_get_user_addresses (allowed_ap); + blacklisted = get_ap_blacklisted (allowed_ap, user_addrs); + g_slist_foreach (user_addrs, (GFunc) g_free, NULL); + g_slist_free (user_addrs); + if (blacklisted) + continue; + + /* No fallback to networks on the invalid list -- we probably already tried them and failed */ + essid = nm_ap_get_essid (allowed_ap); + if (nm_ap_list_get_ap_by_essid (app_data->invalid_ap_list, essid)) + continue; + + curtime = nm_ap_get_timestamp (allowed_ap); + if (curtime->tv_sec > best_timestamp.tv_sec) + { + best_timestamp = *nm_ap_get_timestamp (allowed_ap); + best_ap = allowed_ap; + } + } + nm_ap_list_iter_free (iter); + + if (best_ap) + { + nm_ap_set_broadcast (best_ap, FALSE); + nm_info ("No allowed networks in sight: Brute forcing fall-back '%s'", nm_ap_get_essid (best_ap)); + } + + return best_ap; +} + + /* * nm_device_update_best_ap * @@ -782,10 +879,7 @@ nm_device_802_11_wireless_get_best_ap (NMDevice80211Wireless *self) NMAccessPoint * best_ap = NULL; NMAccessPoint * cur_ap = NULL; NMActRequest * req = NULL; - NMAccessPoint * trusted_best_ap = NULL; - NMAccessPoint * untrusted_best_ap = NULL; - GTimeVal trusted_latest_timestamp = {0, 0}; - GTimeVal untrusted_latest_timestamp = {0, 0}; + GTimeVal best_timestamp = {0, 0}; NMData * app_data; g_return_val_if_fail (self != NULL, NULL); @@ -844,54 +938,29 @@ nm_device_802_11_wireless_get_best_ap (NMDevice80211Wireless *self) if ((tmp_ap = nm_ap_list_get_ap_by_essid (app_data->allowed_ap_list, ap_essid))) { - const GTimeVal *curtime = nm_ap_get_timestamp (tmp_ap); + const GTimeVal * curtime = nm_ap_get_timestamp (tmp_ap); + gboolean blacklisted; + GSList * user_addrs; - /* Only connect to a blacklisted AP if the user has connected - * to this specific AP before. - */ - gboolean blacklisted = nm_ap_has_manufacturer_default_essid (scan_ap); - if (blacklisted) + /* Only connect to a blacklisted AP if the user has connected to this specific AP before */ + user_addrs = nm_ap_get_user_addresses (tmp_ap); + blacklisted = get_ap_blacklisted (scan_ap, user_addrs); + g_slist_foreach (user_addrs, (GFunc) g_free, NULL); + g_slist_free (user_addrs); + + if (!blacklisted && (curtime->tv_sec > best_timestamp.tv_sec)) { - GSList *elt, *user_addrs; - const struct ether_addr *ap_addr; - char char_addr[20]; - - ap_addr = nm_ap_get_address (scan_ap); - user_addrs = nm_ap_get_user_addresses (tmp_ap); - - memset (&char_addr[0], 0, 20); - iw_ether_ntop (ap_addr, &char_addr[0]); - - for (elt = user_addrs; elt; elt = g_slist_next (elt)) - { - if (elt->data && !strcmp (elt->data, &char_addr[0])) - { - blacklisted = FALSE; - break; - } - } - - g_slist_foreach (user_addrs, (GFunc)g_free, NULL); - g_slist_free (user_addrs); - } - - if (!blacklisted && nm_ap_get_trusted (tmp_ap) && (curtime->tv_sec > trusted_latest_timestamp.tv_sec)) - { - trusted_latest_timestamp = *nm_ap_get_timestamp (tmp_ap); - trusted_best_ap = scan_ap; - nm_ap_set_security (trusted_best_ap, nm_ap_get_security (tmp_ap)); - } - else if (!blacklisted && !nm_ap_get_trusted (tmp_ap) && (curtime->tv_sec > untrusted_latest_timestamp.tv_sec)) - { - untrusted_latest_timestamp = *nm_ap_get_timestamp (tmp_ap); - untrusted_best_ap = scan_ap; - nm_ap_set_security (untrusted_best_ap, nm_ap_get_security (tmp_ap)); + best_timestamp = *nm_ap_get_timestamp (tmp_ap); + best_ap = scan_ap; + nm_ap_set_security (best_ap, nm_ap_get_security (tmp_ap)); } } } - best_ap = trusted_best_ap ? trusted_best_ap : untrusted_best_ap; nm_ap_list_iter_free (iter); + if (!best_ap) + best_ap = get_best_fallback_ap (self); + if (best_ap) nm_ap_ref (best_ap); @@ -1752,7 +1821,6 @@ convert_scan_results (gpointer user_data) NMDevice80211Wireless * self; GTimeVal cur_time; NMAPListIter * iter = NULL; - const char * iface; NMData * app_data; NMAccessPointList * ap_list; @@ -1765,12 +1833,15 @@ convert_scan_results (gpointer user_data) return FALSE; } - iface = nm_device_get_iface (NM_DEVICE (self)); app_data = nm_device_get_app_data (NM_DEVICE (self)); if (cb_data->results_len > 0) { if (!process_scan_results (self, cb_data->results, cb_data->results_len)) + { + const char * iface; + iface = nm_device_get_iface (NM_DEVICE (self)); nm_warning ("process_scan_results() on device %s returned an error.", iface); + } /* Once we have the list, copy in any relevant information from our Allowed list. */ nm_ap_list_copy_properties (nm_device_802_11_wireless_ap_list_get (self), app_data->allowed_ap_list); @@ -3035,7 +3106,7 @@ real_activation_failure_handler (NMDevice *dev, if (nm_ap_get_artificial (ap)) { NMAccessPointList * dev_list; - + /* 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 diff --git a/test/nm-set-fallback b/test/nm-set-fallback new file mode 100644 index 0000000000..cc560a8ba8 --- /dev/null +++ b/test/nm-set-fallback @@ -0,0 +1,27 @@ +#! /bin/sh +# +# nm-set-fallback - mark a network as fallback +# +# Robert Love + +BIN=`which gconftool-2` + +if [ "x$1" == "x" ]; then + echo "usage: $0 " + exit 1 +fi + +if [ "x$2" != "xtrue" -a "x$2" != "xfalse" ]; then + echo "usage: $0 " + exit 2 +fi + +KEY="/system/networking/wireless/networks/${1}/fallback" +CURRENT=`$BIN --get $KEY 2>/dev/null` + +if [ "x$CURRENT" != "xtrue" -a "x$CURRENT" != "xfalse" ]; then + echo "Network '$1' is not valid" + exit 3 +fi + +$BIN --set --type=bool $KEY ${2}