core: rework AP handling in nm-device-wifi (Merge branch 'th/rh1025371_wifi_ap_rework')

This reworks and fixes the handling of current_ap in nm-device-wifi.

https://bugzilla.redhat.com/show_bug.cgi?id=1025371

Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
Thomas Haller
2013-12-12 11:36:06 +01:00
11 changed files with 135 additions and 213 deletions

View File

@@ -196,6 +196,8 @@ static void schedule_scanlist_cull (NMDeviceWifi *self);
static gboolean request_wireless_scan (gpointer user_data); static gboolean request_wireless_scan (gpointer user_data);
static void remove_access_point (NMDeviceWifi *device, NMAccessPoint *ap);
/*****************************************************************/ /*****************************************************************/
#define NM_WIFI_ERROR (nm_wifi_error_quark ()) #define NM_WIFI_ERROR (nm_wifi_error_quark ())
@@ -443,6 +445,9 @@ get_ap_by_path (NMDeviceWifi *self, const char *path)
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
GSList *iter; GSList *iter;
if (!path)
return NULL;
for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) { for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) {
if (g_strcmp0 (path, nm_ap_get_dbus_path (NM_AP (iter->data))) == 0) if (g_strcmp0 (path, nm_ap_get_dbus_path (NM_AP (iter->data))) == 0)
return NM_AP (iter->data); return NM_AP (iter->data);
@@ -456,7 +461,10 @@ get_ap_by_supplicant_path (NMDeviceWifi *self, const char *path)
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
GSList *iter; GSList *iter;
for (iter = priv->ap_list; iter && path; iter = g_slist_next (iter)) { if (!path)
return NULL;
for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) {
if (g_strcmp0 (path, nm_ap_get_supplicant_path (NM_AP (iter->data))) == 0) if (g_strcmp0 (path, nm_ap_get_supplicant_path (NM_AP (iter->data))) == 0)
return NM_AP (iter->data); return NM_AP (iter->data);
} }
@@ -464,9 +472,9 @@ get_ap_by_supplicant_path (NMDeviceWifi *self, const char *path)
} }
static NMAccessPoint * static NMAccessPoint *
get_active_ap (NMDeviceWifi *self, find_active_ap (NMDeviceWifi *self,
NMAccessPoint *ignore_ap, NMAccessPoint *ignore_ap,
gboolean match_hidden) gboolean match_hidden)
{ {
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
const char *iface = nm_device_get_iface (NM_DEVICE (self)); const char *iface = nm_device_get_iface (NM_DEVICE (self));
@@ -523,7 +531,7 @@ get_active_ap (NMDeviceWifi *self,
ap_bssid->ether_addr_octet[2], ap_bssid->ether_addr_octet[3], ap_bssid->ether_addr_octet[2], ap_bssid->ether_addr_octet[3],
ap_bssid->ether_addr_octet[4], ap_bssid->ether_addr_octet[5]); ap_bssid->ether_addr_octet[4], ap_bssid->ether_addr_octet[5]);
if (ignore_ap && (ap == ignore_ap)) { if (ap == ignore_ap) {
nm_log_dbg (LOGD_WIFI, " ignored"); nm_log_dbg (LOGD_WIFI, " ignored");
continue; continue;
} }
@@ -592,6 +600,7 @@ get_active_ap (NMDeviceWifi *self,
ap_bssid->ether_addr_octet[4], ap_bssid->ether_addr_octet[5]); ap_bssid->ether_addr_octet[4], ap_bssid->ether_addr_octet[5]);
active_ap = match_nofreq; active_ap = match_nofreq;
goto done;
} }
nm_log_dbg (LOGD_WIFI, " No matching AP found."); nm_log_dbg (LOGD_WIFI, " No matching AP found.");
@@ -628,10 +637,9 @@ update_seen_bssids_cache (NMDeviceWifi *self, NMAccessPoint *ap)
} }
static void static void
set_active_ap (NMDeviceWifi *self, NMAccessPoint *new_ap) set_current_ap (NMDeviceWifi *self, NMAccessPoint *new_ap, gboolean recheck_available_connections, gboolean force_remove_old_ap)
{ {
NMDeviceWifiPrivate *priv; NMDeviceWifiPrivate *priv;
char *old_path = NULL;
NMAccessPoint *old_ap; NMAccessPoint *old_ap;
g_return_if_fail (NM_IS_DEVICE_WIFI (self)); g_return_if_fail (NM_IS_DEVICE_WIFI (self));
@@ -639,10 +647,8 @@ set_active_ap (NMDeviceWifi *self, NMAccessPoint *new_ap)
priv = NM_DEVICE_WIFI_GET_PRIVATE (self); priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
old_ap = priv->current_ap; old_ap = priv->current_ap;
if (old_ap) { if (old_ap == new_ap)
old_path = g_strdup (nm_ap_get_dbus_path (old_ap)); return;
priv->current_ap = NULL;
}
if (new_ap) { if (new_ap) {
priv->current_ap = g_object_ref (new_ap); priv->current_ap = g_object_ref (new_ap);
@@ -656,26 +662,26 @@ set_active_ap (NMDeviceWifi *self, NMAccessPoint *new_ap)
/* Update seen BSSIDs cache */ /* Update seen BSSIDs cache */
update_seen_bssids_cache (self, priv->current_ap); update_seen_bssids_cache (self, priv->current_ap);
} else
priv->current_ap = NULL;
if (old_ap) {
NM80211Mode mode = nm_ap_get_mode (old_ap);
if (force_remove_old_ap || mode == NM_802_11_MODE_ADHOC || mode == NM_802_11_MODE_AP || nm_ap_get_fake (old_ap)) {
remove_access_point (self, old_ap);
if (recheck_available_connections)
nm_device_recheck_available_connections (NM_DEVICE (self));
}
g_object_unref (old_ap);
} }
/* Unref old AP here to ensure object lives if new_ap == old_ap */ g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT);
if (old_ap)
g_object_unref (old_ap);
/* Only notify if it's really changed */
if ( (!old_path && new_ap)
|| (old_path && !new_ap)
|| (old_path && new_ap && strcmp (old_path, nm_ap_get_dbus_path (new_ap))))
g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT);
g_free (old_path);
} }
/* Called both as a GSourceFunc and standalone */ static void
static gboolean periodic_update (NMDeviceWifi *self, NMAccessPoint *ignore_ap)
periodic_update (gpointer user_data)
{ {
NMDeviceWifi *self = NM_DEVICE_WIFI (user_data);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
NMAccessPoint *new_ap; NMAccessPoint *new_ap;
guint32 new_rate; guint32 new_rate;
@@ -688,7 +694,7 @@ periodic_update (gpointer user_data)
*/ */
state = nm_device_get_state (NM_DEVICE (self)); state = nm_device_get_state (NM_DEVICE (self));
if (state != NM_DEVICE_STATE_ACTIVATED) if (state != NM_DEVICE_STATE_ACTIVATED)
return TRUE; return;
/* Only update current AP if we're actually talking to something, otherwise /* Only update current AP if we're actually talking to something, otherwise
* assume the old one (if any) is still valid until we're told otherwise or * assume the old one (if any) is still valid until we're told otherwise or
@@ -698,11 +704,11 @@ periodic_update (gpointer user_data)
if ( supplicant_state < NM_SUPPLICANT_INTERFACE_STATE_AUTHENTICATING if ( supplicant_state < NM_SUPPLICANT_INTERFACE_STATE_AUTHENTICATING
|| supplicant_state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED || supplicant_state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED
|| nm_supplicant_interface_get_scanning (priv->supplicant.iface)) || nm_supplicant_interface_get_scanning (priv->supplicant.iface))
return TRUE; return;
/* In AP mode we currently have nothing to do. */ /* In AP mode we currently have nothing to do. */
if (priv->mode == NM_802_11_MODE_AP) if (priv->mode == NM_802_11_MODE_AP)
return TRUE; return;
/* In IBSS mode, most newer firmware/drivers do "BSS coalescing" where /* In IBSS mode, most newer firmware/drivers do "BSS coalescing" where
* multiple IBSS stations using the same SSID will eventually switch to * multiple IBSS stations using the same SSID will eventually switch to
@@ -724,7 +730,7 @@ periodic_update (gpointer user_data)
nm_ap_set_address (priv->current_ap, &bssid); nm_ap_set_address (priv->current_ap, &bssid);
} }
new_ap = get_active_ap (self, NULL, FALSE); new_ap = find_active_ap (self, ignore_ap, FALSE);
if (new_ap) { if (new_ap) {
/* Try to smooth out the strength. Atmel cards, for example, will give no strength /* Try to smooth out the strength. Atmel cards, for example, will give no strength
* one second and normal strength the next. * one second and normal strength the next.
@@ -736,7 +742,7 @@ periodic_update (gpointer user_data)
} }
} }
if ((new_ap || priv->current_ap) && (new_ap != priv->current_ap)) { if (new_ap != priv->current_ap) {
const struct ether_addr *new_bssid = NULL; const struct ether_addr *new_bssid = NULL;
const GByteArray *new_ssid = NULL; const GByteArray *new_ssid = NULL;
const struct ether_addr *old_bssid = NULL; const struct ether_addr *old_bssid = NULL;
@@ -764,7 +770,7 @@ periodic_update (gpointer user_data)
g_free (old_addr); g_free (old_addr);
g_free (new_addr); g_free (new_addr);
set_active_ap (self, new_ap); set_current_ap (self, new_ap, TRUE, FALSE);
} }
new_rate = wifi_utils_get_rate (priv->wifi_data); new_rate = wifi_utils_get_rate (priv->wifi_data);
@@ -772,7 +778,12 @@ periodic_update (gpointer user_data)
priv->rate = new_rate; priv->rate = new_rate;
g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_BITRATE); g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_BITRATE);
} }
}
static gboolean
periodic_update_cb (gpointer user_data)
{
periodic_update (NM_DEVICE_WIFI (user_data), NULL);
return TRUE; return TRUE;
} }
@@ -787,17 +798,17 @@ bring_up (NMDevice *device, gboolean *no_firmware)
static void static void
remove_access_point (NMDeviceWifi *device, remove_access_point (NMDeviceWifi *device,
NMAccessPoint *ap, NMAccessPoint *ap)
gboolean recheck_available_connections)
{ {
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
g_signal_emit (device, signals[ACCESS_POINT_REMOVED], 0, ap); g_return_if_fail (ap);
priv->ap_list = g_slist_remove (priv->ap_list, ap); g_return_if_fail (ap != priv->current_ap);
g_object_unref (ap); g_return_if_fail (g_slist_find (priv->ap_list, ap));
if (recheck_available_connections) priv->ap_list = g_slist_remove (priv->ap_list, ap);
nm_device_recheck_available_connections (NM_DEVICE (device)); g_signal_emit (device, signals[ACCESS_POINT_REMOVED], 0, ap);
g_object_unref (ap);
} }
static void static void
@@ -805,15 +816,14 @@ remove_all_aps (NMDeviceWifi *self)
{ {
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
/* Remove outdated APs */ if (priv->ap_list) {
while (g_slist_length (priv->ap_list)) { set_current_ap (self, NULL, FALSE, FALSE);
NMAccessPoint *ap = NM_AP (priv->ap_list->data);
remove_access_point (self, ap, FALSE);
}
g_slist_free (priv->ap_list);
priv->ap_list = NULL;
nm_device_recheck_available_connections (NM_DEVICE (self)); while (priv->ap_list)
remove_access_point (self, NM_AP (priv->ap_list->data));
nm_device_recheck_available_connections (NM_DEVICE (self));
}
} }
static void static void
@@ -821,7 +831,6 @@ deactivate (NMDevice *dev)
{ {
NMDeviceWifi *self = NM_DEVICE_WIFI (dev); NMDeviceWifi *self = NM_DEVICE_WIFI (dev);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
NMAccessPoint *orig_ap = nm_device_wifi_get_activation_ap (self);
NMActRequest *req; NMActRequest *req;
NMConnection *connection; NMConnection *connection;
NM80211Mode old_mode = priv->mode; NM80211Mode old_mode = priv->mode;
@@ -840,19 +849,14 @@ deactivate (NMDevice *dev)
cleanup_association_attempt (self, TRUE); cleanup_association_attempt (self, TRUE);
set_active_ap (self, NULL);
priv->rate = 0; priv->rate = 0;
/* If the AP is 'fake', i.e. it wasn't actually found from /* If the AP is 'fake', i.e. it wasn't actually found from
* a scan but the user tried to connect to it manually (maybe it * a scan but the user tried to connect to it manually (maybe it
* was non-broadcasting or something) get rid of it, because 'fake' * was non-broadcasting or something) get rid of it, because 'fake'
* APs should only live for as long as we're connected to them. Fixes * APs should only live for as long as we're connected to them.
* a bug where user-created Ad-Hoc APs are never removed from the scan **/
* list, because scanning is disabled while in Ad-Hoc mode (for stability), set_current_ap (self, NULL, TRUE, FALSE);
* and thus the AP culling never happens. (bgo #569241)
*/
if (orig_ap && nm_ap_get_fake (orig_ap))
remove_access_point (self, orig_ap, TRUE);
/* Reset MAC address back to initial address */ /* Reset MAC address back to initial address */
nm_device_set_hw_addr (dev, priv->initial_hw_addr, "reset", LOGD_WIFI); nm_device_set_hw_addr (dev, priv->initial_hw_addr, "reset", LOGD_WIFI);
@@ -1786,7 +1790,6 @@ merge_scanned_ap (NMDeviceWifi *self,
const GByteArray *ssid; const GByteArray *ssid;
const struct ether_addr *bssid; const struct ether_addr *bssid;
gboolean strict_match = TRUE; gboolean strict_match = TRUE;
NMAccessPoint *current_ap = NULL;
/* Let the manager try to fill in the SSID from seen-bssids lists */ /* Let the manager try to fill in the SSID from seen-bssids lists */
bssid = nm_ap_get_address (merge_ap); bssid = nm_ap_get_address (merge_ap);
@@ -1817,8 +1820,7 @@ merge_scanned_ap (NMDeviceWifi *self,
* constructed from the NMConnection of the activation request, they won't * constructed from the NMConnection of the activation request, they won't
* always be the same as the capabilities of the real AP from the scan. * always be the same as the capabilities of the real AP from the scan.
*/ */
current_ap = nm_device_wifi_get_activation_ap (self); if (priv->current_ap && nm_ap_get_fake (priv->current_ap))
if (current_ap && nm_ap_get_fake (current_ap))
strict_match = FALSE; strict_match = FALSE;
found_ap = get_ap_by_supplicant_path (self, nm_ap_get_supplicant_path (merge_ap)); found_ap = get_ap_by_supplicant_path (self, nm_ap_get_supplicant_path (merge_ap));
@@ -1886,8 +1888,9 @@ cull_scan_list (NMDeviceWifi *self)
const guint prune_interval_s = SCAN_INTERVAL_MAX * 3; const guint prune_interval_s = SCAN_INTERVAL_MAX * 3;
/* Don't cull the associated AP or manually created APs */ /* Don't cull the associated AP or manually created APs */
if (ap == priv->current_ap || nm_ap_get_fake (ap)) if (ap == priv->current_ap)
continue; continue;
g_assert (!nm_ap_get_fake (ap)); /* only the current_ap can be fake */
/* Don't cull APs still known to the supplicant. Since the supplicant /* Don't cull APs still known to the supplicant. Since the supplicant
* doesn't yet emit property updates for "last seen" we have to rely * doesn't yet emit property updates for "last seen" we have to rely
@@ -1901,7 +1904,7 @@ cull_scan_list (NMDeviceWifi *self)
continue; continue;
if (nm_ap_get_last_seen (ap) + prune_interval_s < now) if (nm_ap_get_last_seen (ap) + prune_interval_s < now)
outdated_list = g_slist_append (outdated_list, ap); outdated_list = g_slist_prepend (outdated_list, ap);
} }
/* Remove outdated APs */ /* Remove outdated APs */
@@ -1921,7 +1924,7 @@ cull_scan_list (NMDeviceWifi *self)
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)",
ssid ? "'" : ""); ssid ? "'" : "");
remove_access_point (self, outdated_ap, TRUE); remove_access_point (self, outdated_ap);
removed++; removed++;
} }
g_slist_free (outdated_list); g_slist_free (outdated_list);
@@ -2088,7 +2091,6 @@ link_timeout_cb (gpointer user_data)
NMDevice *dev = NM_DEVICE (user_data); NMDevice *dev = NM_DEVICE (user_data);
NMDeviceWifi *self = NM_DEVICE_WIFI (dev); NMDeviceWifi *self = NM_DEVICE_WIFI (dev);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
NMAccessPoint *ap;
nm_log_warn (LOGD_WIFI, "(%s): link timed out.", nm_device_get_iface (dev)); nm_log_warn (LOGD_WIFI, "(%s): link timed out.", nm_device_get_iface (dev));
@@ -2106,16 +2108,8 @@ link_timeout_cb (gpointer user_data)
* Remove it from the list and if it's actually still present, it'll be * Remove it from the list and if it's actually still present, it'll be
* found in the next scan. * found in the next scan.
*/ */
if (priv->ssid_found == FALSE) { if (priv->ssid_found == FALSE && priv->current_ap)
if (priv->current_ap) { set_current_ap (self, NULL, TRUE, TRUE);
ap = priv->current_ap;
priv->current_ap = NULL;
} else
ap = nm_device_wifi_get_activation_ap (self);
if (ap)
remove_access_point (self, ap, TRUE);
}
nm_device_state_changed (dev, nm_device_state_changed (dev,
NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_FAILED,
@@ -2313,8 +2307,18 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
* schedule the next activation stage. * schedule the next activation stage.
*/ */
if (devstate == NM_DEVICE_STATE_CONFIG) { if (devstate == NM_DEVICE_STATE_CONFIG) {
NMAccessPoint *ap = nm_device_wifi_get_activation_ap (self); NMConnection *connection;
const GByteArray *ssid = ap ? nm_ap_get_ssid (ap) : NULL; NMSettingWireless *s_wifi;
const GByteArray *ssid;
connection = nm_device_get_connection (NM_DEVICE (self));
g_return_if_fail (connection);
s_wifi = nm_connection_get_setting_wireless (connection);
g_return_if_fail (s_wifi);
ssid = nm_setting_wireless_get_ssid (s_wifi);
g_return_if_fail (ssid);
nm_log_info (LOGD_DEVICE | LOGD_WIFI, nm_log_info (LOGD_DEVICE | LOGD_WIFI,
"Activation (%s/wireless) Stage 2 of 5 (Device Configure) " "Activation (%s/wireless) Stage 2 of 5 (Device Configure) "
@@ -2325,7 +2329,7 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)"); ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
nm_device_activate_schedule_stage3_ip_config_start (device); nm_device_activate_schedule_stage3_ip_config_start (device);
} else if (devstate == NM_DEVICE_STATE_ACTIVATED) } else if (devstate == NM_DEVICE_STATE_ACTIVATED)
periodic_update (self); periodic_update (self, NULL);
break; break;
case NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED: case NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED:
if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) { if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) {
@@ -2459,7 +2463,7 @@ supplicant_iface_notify_scanning_cb (NMSupplicantInterface *iface,
/* Run a quick update of current AP when coming out of a scan */ /* Run a quick update of current AP when coming out of a scan */
state = nm_device_get_state (NM_DEVICE (self)); state = nm_device_get_state (NM_DEVICE (self));
if (!scanning && state == NM_DEVICE_STATE_ACTIVATED) if (!scanning && state == NM_DEVICE_STATE_ACTIVATED)
periodic_update (self); periodic_update (self, NULL);
} }
static void static void
@@ -2520,29 +2524,6 @@ handle_auth_or_fail (NMDeviceWifi *self,
return ret; return ret;
} }
static gboolean
is_encrypted (NMAccessPoint *ap, NMConnection *connection)
{
NM80211ApFlags flags;
NM80211ApSecurityFlags wpa_flags, rsn_flags;
g_return_val_if_fail (ap != NULL, FALSE);
g_return_val_if_fail (connection != NULL, FALSE);
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)
return TRUE;
if (wpa_flags & (NM_802_11_AP_SEC_KEY_MGMT_PSK | NM_802_11_AP_SEC_KEY_MGMT_802_1X))
return TRUE;
if (rsn_flags & (NM_802_11_AP_SEC_KEY_MGMT_PSK | NM_802_11_AP_SEC_KEY_MGMT_802_1X))
return TRUE;
return FALSE;
}
/* /*
* supplicant_connection_timeout_cb * supplicant_connection_timeout_cb
* *
@@ -2555,7 +2536,6 @@ supplicant_connection_timeout_cb (gpointer user_data)
NMDevice *dev = NM_DEVICE (user_data); NMDevice *dev = NM_DEVICE (user_data);
NMDeviceWifi *self = NM_DEVICE_WIFI (user_data); NMDeviceWifi *self = NM_DEVICE_WIFI (user_data);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
NMAccessPoint *ap;
NMActRequest *req; NMActRequest *req;
NMConnection *connection; NMConnection *connection;
@@ -2593,9 +2573,8 @@ supplicant_connection_timeout_cb (gpointer user_data)
} }
g_assert (priv->mode == NM_802_11_MODE_INFRA); g_assert (priv->mode == NM_802_11_MODE_INFRA);
ap = nm_device_wifi_get_activation_ap (self);
if (priv->ssid_found && ap && is_encrypted (ap, connection)) { if (priv->ssid_found && nm_connection_get_setting_wireless_security (connection)) {
guint64 timestamp = 0; guint64 timestamp = 0;
gboolean new_secrets = TRUE; gboolean new_secrets = TRUE;
@@ -2672,7 +2651,7 @@ remove_supplicant_timeouts (NMDeviceWifi *self)
static NMSupplicantConfig * static NMSupplicantConfig *
build_supplicant_config (NMDeviceWifi *self, build_supplicant_config (NMDeviceWifi *self,
NMConnection *connection, NMConnection *connection,
NMAccessPoint *ap) guint32 fixed_freq)
{ {
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
NMSupplicantConfig *config = NULL; NMSupplicantConfig *config = NULL;
@@ -2696,9 +2675,7 @@ build_supplicant_config (NMDeviceWifi *self,
if (!nm_supplicant_config_add_setting_wireless (config, if (!nm_supplicant_config_add_setting_wireless (config,
s_wireless, s_wireless,
nm_ap_get_broadcast (ap), fixed_freq)) {
nm_ap_get_freq (ap),
wifi_utils_can_scan_ssid (priv->wifi_data))) {
nm_log_err (LOGD_WIFI, "Couldn't add 802-11-wireless setting to supplicant config."); nm_log_err (LOGD_WIFI, "Couldn't add 802-11-wireless setting to supplicant config.");
goto error; goto error;
} }
@@ -2807,6 +2784,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
const GByteArray *cloned_mac; const GByteArray *cloned_mac;
GSList *iter; GSList *iter;
const char *mode; const char *mode;
const char *ap_path;
ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage1_prepare (dev, reason); ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage1_prepare (dev, reason);
if (ret != NM_ACT_STAGE_RETURN_SUCCESS) if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
@@ -2851,7 +2829,9 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
/* AP mode never uses a specific object or existing scanned AP */ /* AP mode never uses a specific object or existing scanned AP */
if (priv->mode != NM_802_11_MODE_AP) { if (priv->mode != NM_802_11_MODE_AP) {
ap = nm_device_wifi_get_activation_ap (self);
ap_path = nm_active_connection_get_specific_object (NM_ACTIVE_CONNECTION (req));
ap = ap_path ? get_ap_by_path (self, ap_path) : NULL;
if (ap) if (ap)
goto done; goto done;
@@ -2890,7 +2870,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), nm_ap_get_dbus_path (ap)); nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), nm_ap_get_dbus_path (ap));
done: done:
set_active_ap (self, ap); set_current_ap (self, ap, TRUE, FALSE);
return NM_ACT_STAGE_RETURN_SUCCESS; return NM_ACT_STAGE_RETURN_SUCCESS;
} }
@@ -2943,10 +2923,9 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
req = nm_device_get_act_request (dev); req = nm_device_get_act_request (dev);
g_assert (req); g_assert (req);
ap = nm_device_wifi_get_activation_ap (self); ap = priv->current_ap;
if (!ap) { if (!ap) {
nm_log_warn (LOGD_DEVICE | LOGD_WIFI, "act_stage2_config failed due to unexpected missing activation_ap. Abort"); *reason = NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED;
*reason = NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT;
goto out; goto out;
} }
@@ -2993,7 +2972,7 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
ensure_hotspot_frequency (self, s_wireless, ap); ensure_hotspot_frequency (self, s_wireless, ap);
/* Build up the supplicant configuration */ /* Build up the supplicant configuration */
config = build_supplicant_config (self, connection, ap); config = build_supplicant_config (self, connection, nm_ap_get_freq (ap));
if (config == NULL) { if (config == NULL) {
nm_log_err (LOGD_DEVICE | LOGD_WIFI, nm_log_err (LOGD_DEVICE | LOGD_WIFI,
"Activation (%s/wireless): couldn't build wireless configuration.", "Activation (%s/wireless): couldn't build wireless configuration.",
@@ -3023,7 +3002,7 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
} }
if (!priv->periodic_source_id) if (!priv->periodic_source_id)
priv->periodic_source_id = g_timeout_add_seconds (6, periodic_update, self); priv->periodic_source_id = g_timeout_add_seconds (6, periodic_update_cb, self);
/* We'll get stage3 started when the supplicant connects */ /* We'll get stage3 started when the supplicant connects */
ret = NM_ACT_STAGE_RETURN_POSTPONE; ret = NM_ACT_STAGE_RETURN_POSTPONE;
@@ -3060,32 +3039,26 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config)
} }
static gboolean static gboolean
is_static_wep (NMAccessPoint *ap, NMConnection *connection) is_static_wep (NMConnection *connection)
{ {
NM80211ApFlags flags;
NM80211ApSecurityFlags wpa_flags, rsn_flags;
NMSettingWirelessSecurity *s_wsec; NMSettingWirelessSecurity *s_wsec;
const char *key_mgmt; const char *str;
g_return_val_if_fail (ap != NULL, FALSE);
g_return_val_if_fail (connection != NULL, FALSE); g_return_val_if_fail (connection != NULL, FALSE);
flags = nm_ap_get_flags (ap); s_wsec = nm_connection_get_setting_wireless_security (connection);
wpa_flags = nm_ap_get_wpa_flags (ap); if (!s_wsec)
rsn_flags = nm_ap_get_rsn_flags (ap); return FALSE;
if ( (flags & NM_802_11_AP_FLAGS_PRIVACY) str = nm_setting_wireless_security_get_key_mgmt (s_wsec);
&& (wpa_flags == NM_802_11_AP_SEC_NONE) if (g_strcmp0 (str, "none") != 0)
&& (rsn_flags == NM_802_11_AP_SEC_NONE)) { return FALSE;
s_wsec = nm_connection_get_setting_wireless_security (connection);
if (s_wsec) {
key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
if (g_strcmp0 (key_mgmt, "none") == 0)
return TRUE;
}
}
return FALSE; str = nm_setting_wireless_security_get_auth_alg (s_wsec);
if (g_strcmp0 (str, "leap") == 0)
return FALSE;
return TRUE;
} }
static NMActStageReturn static NMActStageReturn
@@ -3095,7 +3068,6 @@ handle_ip_config_timeout (NMDeviceWifi *self,
gboolean *chain_up, gboolean *chain_up,
NMDeviceStateReason *reason) NMDeviceStateReason *reason)
{ {
NMAccessPoint *ap;
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE);
@@ -3105,8 +3077,6 @@ handle_ip_config_timeout (NMDeviceWifi *self,
return ret; return ret;
} }
ap = nm_device_wifi_get_activation_ap (self);
/* If IP configuration times out and it's a static WEP connection, that /* If IP configuration times out and it's a static WEP connection, that
* usually means the WEP key is wrong. WEP's Open System auth mode has * usually means the WEP key is wrong. WEP's Open System auth mode has
* no provision for figuring out if the WEP key is wrong, so you just have * no provision for figuring out if the WEP key is wrong, so you just have
@@ -3114,7 +3084,7 @@ handle_ip_config_timeout (NMDeviceWifi *self,
* types (open, WPA, 802.1x, etc) if the secrets/certs were wrong the * types (open, WPA, 802.1x, etc) if the secrets/certs were wrong the
* connection would have failed before IP configuration. * connection would have failed before IP configuration.
*/ */
if (ap && is_static_wep (ap, connection) && (may_fail == FALSE)) { if (!may_fail && is_static_wep (connection)) {
/* Activation failed, we must have bad encryption key */ /* Activation failed, we must have bad encryption key */
nm_log_warn (LOGD_DEVICE | LOGD_WIFI, nm_log_warn (LOGD_DEVICE | LOGD_WIFI,
"Activation (%s/wireless): could not get IP configuration for " "Activation (%s/wireless): could not get IP configuration for "
@@ -3188,7 +3158,7 @@ activation_success_handler (NMDevice *dev)
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
NMAccessPoint *ap; NMAccessPoint *ap;
struct ether_addr bssid = { {0x0, 0x0, 0x0, 0x0, 0x0, 0x0} }; struct ether_addr bssid = { {0x0, 0x0, 0x0, 0x0, 0x0, 0x0} };
NMAccessPoint *tmp_ap; NMAccessPoint *tmp_ap = NULL;
NMActRequest *req; NMActRequest *req;
NMConnection *connection; NMConnection *connection;
@@ -3201,13 +3171,15 @@ activation_success_handler (NMDevice *dev)
/* Clear wireless secrets tries on success */ /* Clear wireless secrets tries on success */
g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, NULL); g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, NULL);
ap = nm_device_wifi_get_activation_ap (self); ap = priv->current_ap;
/* If the AP isn't fake, it was found in the scan list and all its /* If the AP isn't fake, it was found in the scan list and all its
* details are known. * details are known.
*/ */
if (!ap || !nm_ap_get_fake (ap)) if (!ap || !nm_ap_get_fake (ap)){
ap = NULL;
goto done; goto done;
}
/* If the activate AP was fake, it probably won't have a BSSID at all. /* If the activate AP was fake, it probably won't have a BSSID at all.
* But if activation was successful, the card will know the BSSID. Grab * But if activation was successful, the card will know the BSSID. Grab
@@ -3221,7 +3193,7 @@ activation_success_handler (NMDevice *dev)
if (!nm_ap_get_max_bitrate (ap)) if (!nm_ap_get_max_bitrate (ap))
nm_ap_set_max_bitrate (ap, wifi_utils_get_rate (priv->wifi_data)); nm_ap_set_max_bitrate (ap, wifi_utils_get_rate (priv->wifi_data));
tmp_ap = get_active_ap (self, ap, TRUE); tmp_ap = find_active_ap (self, ap, TRUE);
if (tmp_ap) { if (tmp_ap) {
const GByteArray *ssid = nm_ap_get_ssid (tmp_ap); const GByteArray *ssid = nm_ap_get_ssid (tmp_ap);
@@ -3235,16 +3207,21 @@ activation_success_handler (NMDevice *dev)
nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req),
nm_ap_get_dbus_path (tmp_ap)); nm_ap_get_dbus_path (tmp_ap));
priv->ap_list = g_slist_remove (priv->ap_list, ap);
g_object_unref (ap);
} }
done: done:
periodic_update (self); periodic_update (self, ap);
/* Update seen BSSIDs cache with the connected AP */ /* ap might be already unrefed, because it was a fake_ap. But we don't touch it... */
update_seen_bssids_cache (self, priv->current_ap); if (tmp_ap && ap == priv->current_ap) {
/* Strange, we would expect periodic_update() to find a better AP
* then the fake one and reset it. Reset the fake current_ap to NULL
* now, which will remove the fake ap.
**/
set_current_ap (self, NULL, TRUE, FALSE);
}
/* No need to update seen BSSIDs cache, that is done by set_current_ap() already */
/* Reset scan interval to something reasonable */ /* Reset scan interval to something reasonable */
priv->scan_interval = SCAN_INTERVAL_MIN + (SCAN_INTERVAL_STEP * 2); priv->scan_interval = SCAN_INTERVAL_MIN + (SCAN_INTERVAL_STEP * 2);
@@ -3253,8 +3230,6 @@ done:
static void static void
activation_failure_handler (NMDevice *dev) activation_failure_handler (NMDevice *dev)
{ {
NMDeviceWifi *self = NM_DEVICE_WIFI (dev);
NMAccessPoint *ap;
NMConnection *connection; NMConnection *connection;
connection = nm_device_get_connection (dev); connection = nm_device_get_connection (dev);
@@ -3262,18 +3237,6 @@ activation_failure_handler (NMDevice *dev)
/* Clear wireless secrets tries on failure */ /* Clear wireless secrets tries on failure */
g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, NULL); g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, NULL);
if ((ap = nm_device_wifi_get_activation_ap (self))) {
if (nm_ap_get_fake (ap)) {
/* Fake 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.
*/
remove_access_point (self, ap, TRUE);
}
}
} }
static gboolean static gboolean
@@ -3308,7 +3271,6 @@ device_state_changed (NMDevice *device,
} }
cleanup_association_attempt (self, TRUE); cleanup_association_attempt (self, TRUE);
set_active_ap (self, NULL);
remove_all_aps (self); remove_all_aps (self);
} }
@@ -3364,23 +3326,6 @@ device_state_changed (NMDevice *device,
remove_all_aps (self); remove_all_aps (self);
} }
NMAccessPoint *
nm_device_wifi_get_activation_ap (NMDeviceWifi *self)
{
NMActRequest *req;
const char *ap_path;
g_return_val_if_fail (NM_IS_DEVICE_WIFI (self), NULL);
req = nm_device_get_act_request (NM_DEVICE (self));
if (!req)
return NULL;
ap_path = nm_active_connection_get_specific_object (NM_ACTIVE_CONNECTION (req));
return ap_path ? get_ap_by_path (self, ap_path) : NULL;
}
static void static void
set_enabled (NMDevice *device, gboolean enabled) set_enabled (NMDevice *device, gboolean enabled)
{ {
@@ -3486,7 +3431,6 @@ dispose (GObject *object)
priv->supplicant.mgr = NULL; priv->supplicant.mgr = NULL;
} }
set_active_ap (self, NULL);
remove_all_aps (self); remove_all_aps (self);
if (priv->wifi_data) if (priv->wifi_data)

View File

@@ -91,8 +91,6 @@ GType nm_device_wifi_get_type (void);
NMDevice *nm_device_wifi_new (NMPlatformLink *platform_device); NMDevice *nm_device_wifi_new (NMPlatformLink *platform_device);
NMAccessPoint * nm_device_wifi_get_activation_ap (NMDeviceWifi *self);
RfKillState nm_device_wifi_get_ipw_rfkill_state (NMDeviceWifi *self); RfKillState nm_device_wifi_get_ipw_rfkill_state (NMDeviceWifi *self);
G_END_DECLS G_END_DECLS

View File

@@ -794,7 +794,7 @@ nm_ap_set_ssid (NMAccessPoint *ap, const GByteArray * ssid)
priv = NM_AP_GET_PRIVATE (ap); priv = NM_AP_GET_PRIVATE (ap);
if ((ssid == priv->ssid) && ssid == NULL) if (ssid == priv->ssid)
return; return;
/* same SSID */ /* same SSID */

View File

@@ -334,9 +334,7 @@ nm_supplicant_config_get_blobs (NMSupplicantConfig * self)
gboolean gboolean
nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self, nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
NMSettingWireless * setting, NMSettingWireless * setting,
gboolean is_broadcast, guint32 fixed_freq)
guint32 fixed_freq,
gboolean has_scan_capa_ssid)
{ {
NMSupplicantConfigPrivate *priv; NMSupplicantConfigPrivate *priv;
gboolean is_adhoc, is_ap; gboolean is_adhoc, is_ap;
@@ -353,12 +351,8 @@ nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
is_ap = (mode && !strcmp (mode, "ap")) ? TRUE : FALSE; is_ap = (mode && !strcmp (mode, "ap")) ? TRUE : FALSE;
if (is_adhoc || is_ap) if (is_adhoc || is_ap)
priv->ap_scan = 2; priv->ap_scan = 2;
else if (is_broadcast == FALSE) { else
/* drivers that support scanning specific SSIDs should use priv->ap_scan = 1;
* ap_scan=1, while those that do not should use ap_scan=2.
*/
priv->ap_scan = has_scan_capa_ssid ? 1 : 2;
}
id = nm_setting_wireless_get_ssid (setting); id = nm_setting_wireless_get_ssid (setting);
if (!nm_supplicant_config_add_option (self, "ssid", (char *) id->data, id->len, FALSE)) { if (!nm_supplicant_config_add_option (self, "ssid", (char *) id->data, id->len, FALSE)) {

View File

@@ -65,9 +65,7 @@ GHashTable *nm_supplicant_config_get_blobs (NMSupplicantConfig *self);
gboolean nm_supplicant_config_add_setting_wireless (NMSupplicantConfig *self, gboolean nm_supplicant_config_add_setting_wireless (NMSupplicantConfig *self,
NMSettingWireless *setting, NMSettingWireless *setting,
gboolean is_broadcast, guint32 fixed_freq);
guint32 adhoc_freq,
gboolean has_scan_capa_ssid);
gboolean nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, gboolean nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
NMSettingWirelessSecurity *setting, NMSettingWirelessSecurity *setting,

View File

@@ -173,7 +173,7 @@ test_wifi_open (void)
config = nm_supplicant_config_new (); config = nm_supplicant_config_new ();
success = nm_supplicant_config_add_setting_wireless (config, s_wifi, TRUE, 0, TRUE); success = nm_supplicant_config_add_setting_wireless (config, s_wifi, 0);
ASSERT (success == TRUE, ASSERT (success == TRUE,
"wifi-open", "failed to add wireless setting to supplicant config."); "wifi-open", "failed to add wireless setting to supplicant config.");
@@ -272,7 +272,7 @@ test_wifi_wep_key (const char *detail,
config = nm_supplicant_config_new (); config = nm_supplicant_config_new ();
success = nm_supplicant_config_add_setting_wireless (config, s_wifi, TRUE, 0, TRUE); success = nm_supplicant_config_add_setting_wireless (config, s_wifi, 0);
ASSERT (success == TRUE, ASSERT (success == TRUE,
detail, "failed to add wireless setting to supplicant config."); detail, "failed to add wireless setting to supplicant config.");
@@ -405,7 +405,7 @@ test_wifi_wpa_psk (const char *detail,
config = nm_supplicant_config_new (); config = nm_supplicant_config_new ();
success = nm_supplicant_config_add_setting_wireless (config, s_wifi, TRUE, 0, TRUE); success = nm_supplicant_config_add_setting_wireless (config, s_wifi, 0);
ASSERT (success == TRUE, ASSERT (success == TRUE,
detail, "failed to add wireless setting to supplicant config."); detail, "failed to add wireless setting to supplicant config.");

View File

@@ -806,7 +806,6 @@ wifi_nl80211_init (const char *iface, int ifindex)
nl80211->freqs = device_info.freqs; nl80211->freqs = device_info.freqs;
nl80211->num_freqs = device_info.num_freqs; nl80211->num_freqs = device_info.num_freqs;
nl80211->parent.can_scan_ssid = device_info.can_scan_ssid;
nl80211->parent.caps = device_info.caps; nl80211->parent.caps = device_info.caps;
nm_log_info (LOGD_HW | LOGD_WIFI, nm_log_info (LOGD_HW | LOGD_WIFI,

View File

@@ -30,7 +30,6 @@ struct WifiData {
char *iface; char *iface;
int ifindex; int ifindex;
NMDeviceWifiCapabilities caps; NMDeviceWifiCapabilities caps;
gboolean can_scan_ssid;
NM80211Mode (*get_mode) (WifiData *data); NM80211Mode (*get_mode) (WifiData *data);

View File

@@ -630,7 +630,6 @@ wifi_wext_init (const char *iface, int ifindex, gboolean check_scan)
*/ */
scan_capa_range = (struct iw_range_with_scan_capa *) &range; scan_capa_range = (struct iw_range_with_scan_capa *) &range;
if (scan_capa_range->scan_capa & NM_IW_SCAN_CAPA_ESSID) { if (scan_capa_range->scan_capa & NM_IW_SCAN_CAPA_ESSID) {
wext->parent.can_scan_ssid = TRUE;
nm_log_info (LOGD_HW | LOGD_WIFI, nm_log_info (LOGD_HW | LOGD_WIFI,
"(%s): driver supports SSID scans (scan_capa 0x%02X).", "(%s): driver supports SSID scans (scan_capa 0x%02X).",
wext->parent.iface, wext->parent.iface,

View File

@@ -78,13 +78,6 @@ wifi_utils_get_caps (WifiData *data)
return data->caps; return data->caps;
} }
gboolean
wifi_utils_can_scan_ssid (WifiData *data)
{
g_return_val_if_fail (data != NULL, FALSE);
return data->can_scan_ssid;
}
NM80211Mode NM80211Mode
wifi_utils_get_mode (WifiData *data) wifi_utils_get_mode (WifiData *data)
{ {

View File

@@ -37,8 +37,6 @@ void wifi_utils_deinit (WifiData *data);
NMDeviceWifiCapabilities wifi_utils_get_caps (WifiData *data); NMDeviceWifiCapabilities wifi_utils_get_caps (WifiData *data);
gboolean wifi_utils_can_scan_ssid (WifiData *data);
NM80211Mode wifi_utils_get_mode (WifiData *data); NM80211Mode wifi_utils_get_mode (WifiData *data);
gboolean wifi_utils_set_mode (WifiData *data, const NM80211Mode mode); gboolean wifi_utils_set_mode (WifiData *data, const NM80211Mode mode);