[network-manager-netbook: 1/4] Fix a bug where wrong AP would be used for connected wifi items.
- From: Tambet Ingo <tambeti src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [network-manager-netbook: 1/4] Fix a bug where wrong AP would be used for connected wifi items.
- Date: Tue, 10 Nov 2009 10:06:38 +0000 (UTC)
commit 6b0f6413767138634906ea3f922554b1bca3d3d7
Author: Tambet Ingo <tambet gmail com>
Date: Wed Oct 7 15:34:00 2009 +0300
Fix a bug where wrong AP would be used for connected wifi items.
src/nmn-wifi-handler.c | 159 +++++++++++++++++++++++++++++++++++++-----------
1 files changed, 123 insertions(+), 36 deletions(-)
---
diff --git a/src/nmn-wifi-handler.c b/src/nmn-wifi-handler.c
index 5f49b92..27c8bfc 100644
--- a/src/nmn-wifi-handler.c
+++ b/src/nmn-wifi-handler.c
@@ -51,6 +51,47 @@ nmn_wifi_handler_new (NmnNMData *nm_data,
NULL));
}
+static gboolean
+aps_are_compatible (NMAccessPoint *ap1, NMAccessPoint *ap2)
+{
+ const GByteArray *ssid1;
+ const GByteArray *ssid2;
+
+ ssid1 = nm_access_point_get_ssid (ap1);
+ ssid2 = nm_access_point_get_ssid (ap2);
+
+ /* SSIDs do not match */
+ if (!ssid1 || !ssid2 || ssid1->len != ssid2->len || memcmp (ssid1->data, ssid2->data, ssid1->len))
+ return FALSE;
+
+ if (nm_access_point_get_mode (ap1) == nm_access_point_get_mode (ap2) &&
+ nm_access_point_get_flags (ap1) == nm_access_point_get_flags (ap2) &&
+ nm_access_point_get_wpa_flags (ap1) == nm_access_point_get_wpa_flags (ap2) &&
+ nm_access_point_get_rsn_flags (ap1) == nm_access_point_get_rsn_flags (ap2))
+ return TRUE;
+
+ return FALSE;
+}
+
+static NMAccessPoint *
+find_best_compatible_ap (const GPtrArray *aps, NMAccessPoint *current_ap)
+{
+ NMAccessPoint *best_ap = NULL;
+ int i;
+
+ for (i = 0; aps && i < aps->len; i++) {
+ NMAccessPoint *ap = NM_ACCESS_POINT (g_ptr_array_index (aps, i));
+
+ if (ap == current_ap || !aps_are_compatible (current_ap, ap))
+ continue;
+
+ if (!best_ap || nm_access_point_get_strength (best_ap) < nm_access_point_get_strength (ap))
+ best_ap = ap;
+ }
+
+ return best_ap;
+}
+
static NMAccessPoint *
find_best_ap_for_connection (NMDeviceWifi *device,
NMExportedConnection *connection)
@@ -77,50 +118,64 @@ find_best_ap_for_connection (NMDeviceWifi *device,
}
static void
-update_items (NmnWifiHandler *self)
+ap_updated (NMAccessPoint *ap,
+ GParamSpec *pspec,
+ gpointer user_data)
{
- GSList *list;
+ NmnDeviceHandler *handler = NMN_DEVICE_HANDLER (user_data);
+ GSList *items;
GSList *iter;
- NMDeviceWifi *device;
-
- device = NM_DEVICE_WIFI (nmn_device_handler_get_device (NMN_DEVICE_HANDLER (self)));
- list = nmn_device_handler_get_items (NMN_DEVICE_HANDLER (self));
- for (iter = list; iter; iter = iter->next) {
+ items = nmn_device_handler_get_items (handler);
+ for (iter = items; iter; iter = iter->next) {
NmnWifiItem *item = NMN_WIFI_ITEM (iter->data);
- NMAccessPoint *current_ap = nmn_wifi_item_get_ap (item);
- NMAccessPoint *best_ap;
-
- best_ap = nm_device_wifi_get_active_access_point (device);
- if (!best_ap) {
- NMExportedConnection *exported;
-
- exported = nmn_network_item_get_connection (NMN_NETWORK_ITEM (item));
- best_ap = find_best_ap_for_connection (device, exported);
- }
-
- if (!best_ap)
- nmn_item_remove_requested (NMN_ITEM (item));
- else if (best_ap != current_ap)
- nmn_wifi_item_set_ap (item, best_ap);
+ NMAccessPoint *item_ap = nmn_wifi_item_get_ap (item);
+ NMDeviceWifi *device;
+ NMAccessPoint *new_ap;
+
+ /* Don't touch activated items, these are handled by active_ap_changed */
+ if (nmn_network_item_get_status (NMN_NETWORK_ITEM (item)) != NMN_NETWORK_ITEM_STATUS_DISCONNECTED)
+ continue;
+
+ /* not us */
+ if (item_ap != ap && !aps_are_compatible (ap, item_ap))
+ continue;
+
+ /* Do we have a better compatible AP for this item? */
+ device = NM_DEVICE_WIFI (nmn_device_handler_get_device (handler));
+ new_ap = find_best_compatible_ap (nm_device_wifi_get_access_points (device), item_ap);
+ if (new_ap)
+ nmn_wifi_item_set_ap (item, new_ap);
}
}
static void
-ap_updated (NMAccessPoint *ap,
- GParamSpec *pspec,
- gpointer user_data)
-{
- update_items (NMN_WIFI_HANDLER (user_data));
-}
-
-static void
ap_removed (NMDeviceWifi *device,
NMAccessPoint *ap,
gpointer user_data)
{
+ GSList *items;
+ GSList *iter;
+
g_signal_handlers_disconnect_by_func (ap, "notify", ap_updated);
- update_items (NMN_WIFI_HANDLER (user_data));
+
+ items = nmn_device_handler_get_items (NMN_DEVICE_HANDLER (user_data));
+ for (iter = items; iter; iter = iter->next) {
+ NmnWifiItem *item = NMN_WIFI_ITEM (iter->data);
+ NMAccessPoint *new_ap;
+
+ /* not us */
+ if (nmn_wifi_item_get_ap (item) != ap)
+ continue;
+
+ /* Do we have another compatible AP for this item? */
+ new_ap = find_best_compatible_ap (nm_device_wifi_get_access_points (device), ap);
+ if (new_ap)
+ nmn_wifi_item_set_ap (item, new_ap);
+ else
+ /* Nope, remove the item */
+ nmn_item_remove_requested (NMN_ITEM (item));
+ }
}
static void
@@ -166,10 +221,8 @@ ap_added (NMDeviceWifi *device,
GSList *iter;
/* Catch the signals of the new AP */
- g_signal_connect (ap, "notify", G_CALLBACK (ap_updated), handler);
-
- /* */
- update_items (NMN_WIFI_HANDLER (handler));
+ g_signal_connect (ap, "notify", G_CALLBACK (ap_updated), user_data);
+ ap_updated (ap, NULL, user_data);
/* Maybe there's an existing connection for it which hasn't been added yet? */
list = nmn_device_handler_get_connections (handler);
@@ -179,12 +232,46 @@ ap_added (NMDeviceWifi *device,
g_slist_free (list);
}
+static gboolean
+active_ap_changed_cb (gpointer user_data)
+{
+ NmnDeviceHandler *handler = NMN_DEVICE_HANDLER (user_data);
+ NMDeviceWifi *device;
+ GSList *items;
+ GSList *iter;
+ NMAccessPoint *active_ap;
+
+ device = NM_DEVICE_WIFI (nmn_device_handler_get_device (handler));
+ active_ap = nm_device_wifi_get_active_access_point (device);
+ items = nmn_device_handler_get_items (NMN_DEVICE_HANDLER (user_data));
+
+ for (iter = items; iter; iter = iter->next) {
+ NmnWifiItem *item = NMN_WIFI_ITEM (iter->data);
+
+ /* Don't touch inactive items */
+ if (nmn_network_item_get_status (NMN_NETWORK_ITEM (item)) == NMN_NETWORK_ITEM_STATUS_DISCONNECTED)
+ continue;
+
+ /* If an item gets deactivated, find a new best AP for it */
+ if (!active_ap)
+ active_ap = find_best_compatible_ap (nm_device_wifi_get_access_points (device),
+ nmn_wifi_item_get_ap (item));
+
+ if (active_ap && nmn_wifi_item_get_ap (item) != active_ap)
+ nmn_wifi_item_set_ap (item, active_ap);
+ }
+
+ return FALSE;
+}
+
static void
active_ap_changed (NMDeviceWifi *device,
GParamSpec *pspec,
gpointer user_data)
{
- update_items (NMN_WIFI_HANDLER (user_data));
+ /* We need to delay this a bit, otherwise we haven't received all the other state
+ change notification yet and we don't know the correct state */
+ g_timeout_add_seconds (2, active_ap_changed_cb, user_data);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]