Commit 6b4bfea2 authored by Dan Williams's avatar Dan Williams

2004-10-11 Dan Williams <dcbw@redhat.com>

	* src/NetworkManagerAP.c
		- (nm_ap_new, nm_ap_new_from_ap): Don't crash when we don't have
			enough RAM to allocate new AP structures, but return NULL instead

	* src/NetworkManagerAPList.[ch]
		- (nm_ap_list_is_empty): new function
		- (nm_ap_list_combine): new function, combine two access point lists
		- (nm_ap_list_copy_keys): new function, copy keys from one list
			into another

	* src/NetworkManagerDevice.[ch]
		- Rename some functions to be clearer:
			nm_device_get_best_ap_frozen -> nm_device_is_best_ap_frozen
			nm_device_just_activated     -> nm_device_is_just_activated
			nm_device_activating         -> nm_device_is_activating
			nm_device_now_scanning       -> nm_device_is_scanning
		- Cache the last 4 scans so that the access point list is more stable.
			We combine the lastest two scans and use that as the AP list,
			and diff that combined list against the combination of the earliest
			two cached scans for the WirelessNetworkAppeared/Dissappeared signals


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@210 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
parent 2844d765
2004-10-11 Dan Williams <dcbw@redhat.com>
* src/NetworkManagerAP.c
- (nm_ap_new, nm_ap_new_from_ap): Don't crash when we don't have
enough RAM to allocate new AP structures, but return NULL instead
* src/NetworkManagerAPList.[ch]
- (nm_ap_list_is_empty): new function
- (nm_ap_list_combine): new function, combine two access point lists
- (nm_ap_list_copy_keys): new function, copy keys from one list
into another
* src/NetworkManagerDevice.[ch]
- Rename some functions to be clearer:
nm_device_get_best_ap_frozen -> nm_device_is_best_ap_frozen
nm_device_just_activated -> nm_device_is_just_activated
nm_device_activating -> nm_device_is_activating
nm_device_now_scanning -> nm_device_is_scanning
- Cache the last 4 scans so that the access point list is more stable.
We combine the lastest two scans and use that as the AP list,
and diff that combined list against the combination of the earliest
two cached scans for the WirelessNetworkAppeared/Dissappeared signals
2004-10-08 John (J5) Palmieri <johnp@redhat.com>
* info-daemon/NWManagerInfo.h
......
......@@ -59,7 +59,10 @@ NMAccessPoint * nm_ap_new (void)
ap = g_new0 (NMAccessPoint, 1);
if (!ap)
syslog( LOG_ERR, "nm_ap_new() could not allocate a new user access point info structure. Not enough memory?" );
{
syslog (LOG_ERR, "nm_ap_new() could not allocate a new user access point info structure. Not enough memory?");
return (NULL);
}
ap->refcount = 1;
......@@ -85,7 +88,10 @@ NMAccessPoint * nm_ap_new_from_ap (NMAccessPoint *src_ap)
new_ap = nm_ap_new();
if (!new_ap)
syslog( LOG_ERR, "nm_ap_new_from_uap() could not allocate a new user access point info structure. Not enough memory?" );
{
syslog (LOG_ERR, "nm_ap_new_from_uap() could not allocate a new user access point structure. Not enough memory?");
return (NULL);
}
new_ap->refcount = 1;
......@@ -399,7 +405,7 @@ void nm_ap_set_trusted (NMAccessPoint *ap, gboolean trusted)
* Return the encryption method the user specified for this access point.
*
*/
NMAPEncMethod nm_ap_get_enc_method (NMAccessPoint *ap)
const NMAPEncMethod nm_ap_get_enc_method (NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, TRUE);
......
......@@ -77,6 +77,6 @@ void nm_ap_set_matched (NMAccessPoint *ap, gboolean matched);
gboolean nm_ap_get_trusted (NMAccessPoint *ap);
void nm_ap_set_trusted (NMAccessPoint *ap, gboolean trusted);
NMAPEncMethod nm_ap_get_enc_method (NMAccessPoint *ap);
const NMAPEncMethod nm_ap_get_enc_method (NMAccessPoint *ap);
#endif
......@@ -116,6 +116,19 @@ void nm_ap_list_unref (NMAccessPointList *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
*
......@@ -291,6 +304,94 @@ void nm_ap_list_populate (NMAccessPointList *list, NMData *data)
}
/*
* nm_ap_list_combine
*
* Combine two access point lists into one. This is a simple OR operation, where each
* unique access point in either list is present in the final, combined list.
*
* NOTE: locks NMAccessPointList arguments
*/
NMAccessPointList * nm_ap_list_combine (NMAccessPointList *list1, NMAccessPointList *list2)
{
NMAccessPointList *final_list = NULL;
NMAPListIter *iter;
NMAccessPoint *ap;
final_list = nm_ap_list_new (NETWORK_TYPE_DEVICE);
if (!final_list)
return (NULL);
/* Add all APs in the first list */
if (list1 && (iter = nm_ap_list_iter_new (list1)))
{
while ((ap = nm_ap_list_iter_next (iter)))
{
NMAccessPoint *new_ap = nm_ap_new_from_ap (ap);
if (new_ap)
nm_ap_list_append_ap (final_list, new_ap);
}
nm_ap_list_iter_free (iter);
}
/* Add all APs in the second list not already added from the first */
if (list2 && (iter = nm_ap_list_iter_new (list2)))
{
while ((ap = nm_ap_list_iter_next (iter)))
{
if (!nm_ap_list_get_ap_by_essid (final_list, nm_ap_get_essid (ap)))
{
NMAccessPoint *new_ap = nm_ap_new_from_ap (ap);
if (new_ap)
nm_ap_list_append_ap (final_list, new_ap);
}
}
nm_ap_list_iter_free (iter);
}
if (nm_ap_list_is_empty (final_list))
{
nm_ap_list_unref (final_list);
final_list = NULL;
}
return (final_list);
}
/*
* nm_ap_list_copy_keys
*
* Update the keys and encryption methods 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_keys (NMAccessPointList *dest, NMAccessPointList *source)
{
NMAPListIter *iter;
NMAccessPoint *dest_ap;
g_return_if_fail (dest != NULL);
g_return_if_fail (source != NULL);
if ((iter = nm_ap_list_iter_new (dest)))
{
while ((dest_ap = nm_ap_list_iter_next (iter)))
{
NMAccessPoint *src_ap = NULL;
if ((src_ap = nm_ap_list_get_ap_by_essid (source, nm_ap_get_essid (dest_ap))))
{
nm_ap_set_invalid (dest_ap, nm_ap_get_invalid (src_ap));
nm_ap_set_enc_key_source (dest_ap, nm_ap_get_enc_key_source (src_ap), nm_ap_get_enc_method (src_ap));
}
}
nm_ap_list_iter_free (iter);
}
}
/*
* nm_ap_list_diff
*
......@@ -327,7 +428,6 @@ void nm_ap_list_diff (NMData *data, NMDevice *dev, NMAccessPointList *old, NMAcc
{
nm_ap_set_matched (old_ap, TRUE);
nm_ap_set_matched (new_ap, TRUE);
nm_ap_set_invalid (new_ap, nm_ap_get_invalid (old_ap));
}
else
nm_dbus_signal_wireless_network_change (data->dbus_connection, dev, old_ap, TRUE);
......
......@@ -41,6 +41,8 @@ NMAccessPointList * nm_ap_list_new (NMNetworkType type);
void nm_ap_list_ref (NMAccessPointList *list);
void nm_ap_list_unref (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);
......@@ -50,6 +52,8 @@ void nm_ap_list_update_network (NMAccessPointList *list, const char *network,
void nm_ap_list_populate (NMAccessPointList *list, NMData *data);
void nm_ap_list_copy_keys (NMAccessPointList *dest, NMAccessPointList *source);
NMAccessPointList * nm_ap_list_combine (NMAccessPointList *list1, NMAccessPointList *list2);
void nm_ap_list_diff (NMData *data, NMDevice *dev, NMAccessPointList *old, NMAccessPointList *new);
gboolean nm_ap_list_lock (NMAccessPointList *list);
......
......@@ -1254,9 +1254,9 @@ static DBusHandlerResult nm_dbus_nm_message_handler (DBusConnection *connection,
{
if ((reply_message = dbus_message_new_method_return (message)))
{
if (data->active_device && nm_device_activating (data->active_device))
if (data->active_device && nm_device_is_activating (data->active_device))
{
if (nm_device_is_wireless (data->active_device) && nm_device_now_scanning (data->active_device))
if (nm_device_is_wireless (data->active_device) && nm_device_is_scanning (data->active_device))
dbus_message_append_args (reply_message, DBUS_TYPE_STRING, "scanning", DBUS_TYPE_INVALID);
else
dbus_message_append_args (reply_message, DBUS_TYPE_STRING, "connecting", DBUS_TYPE_INVALID);
......
......@@ -55,7 +55,17 @@ typedef struct NMDeviceWirelessOptions
gint8 strength;
GMutex *scan_mutex;
/* We keep a couple lists around since wireless cards
* are a bit flakey and don't report the same access
* points every time. The lists get merged and diffed
* to figure out the "real" list, but the latest_ap_list
* is always the most-current scan.
*/
NMAccessPointList *ap_list;
NMAccessPointList *cached_ap_list1;
NMAccessPointList *cached_ap_list2;
NMAccessPointList *cached_ap_list3;
NMAccessPointList *cached_ap_list4;
NMAccessPoint *best_ap;
GMutex *best_ap_mutex;
......@@ -366,7 +376,16 @@ void nm_device_unref (NMDevice *dev)
if (nm_device_is_wireless (dev))
{
g_mutex_free (dev->options.wireless.scan_mutex);
nm_ap_list_unref (dev->options.wireless.ap_list);
if (dev->options.wireless.ap_list)
nm_ap_list_unref (dev->options.wireless.ap_list);
if (dev->options.wireless.cached_ap_list1)
nm_ap_list_unref (dev->options.wireless.cached_ap_list1);
if (dev->options.wireless.cached_ap_list2)
nm_ap_list_unref (dev->options.wireless.cached_ap_list2);
if (dev->options.wireless.cached_ap_list3)
nm_ap_list_unref (dev->options.wireless.cached_ap_list3);
if (dev->options.wireless.cached_ap_list4)
nm_ap_list_unref (dev->options.wireless.cached_ap_list4);
nm_ap_unref (dev->options.wireless.best_ap);
g_mutex_free (dev->options.wireless.best_ap_mutex);
}
......@@ -1463,13 +1482,13 @@ static gpointer nm_device_activation_worker (gpointer user_data)
/*
* nm_device_just_activated
* nm_device_is_just_activated
*
* Check if the device was just activated successfully or not. If so, clear
* its just_activated flag and return TRUE. If its not activated yet, return FALSE.
*
*/
gboolean nm_device_just_activated (NMDevice *dev)
gboolean nm_device_is_just_activated (NMDevice *dev)
{
g_return_val_if_fail (dev != NULL, FALSE);
......@@ -1484,12 +1503,12 @@ gboolean nm_device_just_activated (NMDevice *dev)
/*
* nm_device_activating
* nm_device_is_activating
*
* Return whether or not the device is currently activating itself.
*
*/
gboolean nm_device_activating (NMDevice *dev)
gboolean nm_device_is_activating (NMDevice *dev)
{
g_return_val_if_fail (dev != NULL, FALSE);
......@@ -1507,7 +1526,7 @@ void nm_device_activation_cancel (NMDevice *dev)
{
g_return_if_fail (dev != NULL);
if (nm_device_activating (dev))
if (nm_device_is_activating (dev))
{
syslog (LOG_DEBUG, "nm_device_activation_cancel(%s): cancelling...", nm_device_get_iface (dev));
dev->quit_activation = TRUE;
......@@ -1517,7 +1536,7 @@ void nm_device_activation_cancel (NMDevice *dev)
* The other problem with waiting here is that we hold up dbus traffic
* that we should respond to.
*/
while (nm_device_activating (dev))
while (nm_device_is_activating (dev))
g_usleep (G_USEC_PER_SEC / 2);
}
}
......@@ -1556,14 +1575,14 @@ gboolean nm_device_deactivate (NMDevice *dev, gboolean just_added)
/*
* nm_device_now_scanning
* nm_device_is_scanning
*
* Returns whether the device is scanning, awaiting an access point to connect to.
* Note that this does NOT get set when the device is actually scanning, just
* when it is waiting for a valid access point to connect to.
*
*/
gboolean nm_device_now_scanning (NMDevice *dev)
gboolean nm_device_is_scanning (NMDevice *dev)
{
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (nm_device_is_wireless (dev), FALSE);
......@@ -1751,7 +1770,7 @@ void nm_device_unfreeze_best_ap (NMDevice *dev)
dev->options.wireless.freeze_best_ap = FALSE;
}
gboolean nm_device_get_best_ap_frozen (NMDevice *dev)
gboolean nm_device_is_best_ap_frozen (NMDevice *dev)
{
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (nm_device_is_wireless (dev), FALSE);
......@@ -1832,7 +1851,7 @@ void nm_device_update_best_ap (NMDevice *dev)
* not, we can "unfreeze" the best ap if its been frozen already).
* If it is, we don't change the best ap here.
*/
if (nm_device_get_best_ap_frozen (dev))
if (nm_device_is_best_ap_frozen (dev))
{
NMAccessPoint *best_ap = nm_device_get_best_ap (dev);
......@@ -1929,7 +1948,8 @@ static void nm_device_do_normal_scan (NMDevice *dev)
wireless_scan_head scan_results = { NULL, 0 };
wireless_scan *tmp_ap;
int err;
NMAccessPointList *old_ap_list = nm_device_ap_list_get (dev);
NMAccessPointList *old_ap_list = NULL;
NMAccessPointList *temp_list;
err = iw_scan (iwlib_socket, nm_device_get_iface (dev), WIRELESS_EXT, &scan_results);
if ((err == -1) && (errno == ENODATA))
......@@ -1947,15 +1967,23 @@ static void nm_device_do_normal_scan (NMDevice *dev)
}
}
/* Clear out the ap list for this device in preparation for any new ones */
dev->options.wireless.ap_list = nm_ap_list_new (NETWORK_TYPE_DEVICE);
if (!(dev->options.wireless.ap_list))
/* New list for current scan data */
temp_list = nm_ap_list_new (NETWORK_TYPE_DEVICE);
if (!temp_list)
{
nm_dispose_scan_results (scan_results.result);
close (iwlib_socket);
return;
}
/* Shift all previous cached scan results and dispose of the oldest one. */
if (dev->options.wireless.cached_ap_list4)
nm_ap_list_unref (dev->options.wireless.cached_ap_list4);
dev->options.wireless.cached_ap_list4 = dev->options.wireless.cached_ap_list3;
dev->options.wireless.cached_ap_list3 = dev->options.wireless.cached_ap_list2;
dev->options.wireless.cached_ap_list2 = dev->options.wireless.cached_ap_list1;
dev->options.wireless.cached_ap_list1 = temp_list;
/* Iterate over scan results and pick a "most" preferred access point. */
tmp_ap = scan_results.result;
while (tmp_ap)
......@@ -1984,24 +2012,39 @@ static void nm_device_do_normal_scan (NMDevice *dev)
if (tmp_ap->b.has_freq)
nm_ap_set_freq (nm_ap, tmp_ap->b.freq);
/* Merge settings from wireless networks, mainly Keys */
/* Merge settings from user-approved wireless networks, mainly encryption keys */
if ((list_ap = nm_ap_list_get_ap_by_essid (data->allowed_ap_list, nm_ap_get_essid (nm_ap))))
{
nm_ap_set_timestamp (nm_ap, nm_ap_get_timestamp (list_ap));
nm_ap_set_enc_key_source (nm_ap, nm_ap_get_enc_key_source (list_ap), nm_ap_get_enc_method (list_ap));
}
/* Add the AP to the device's AP list */
nm_device_ap_list_add_ap (dev, nm_ap);
nm_ap_list_append_ap (dev->options.wireless.cached_ap_list1, nm_ap);
}
tmp_ap = tmp_ap->next;
}
nm_dispose_scan_results (scan_results.result);
close (iwlib_socket);
/* Dispose of the old list of available access points the card knows about */
if (nm_device_ap_list_get (dev))
nm_ap_list_unref (nm_device_ap_list_get (dev));
/* Compose the current access point list for the card based on the past two scans. This
* is to achieve some stability in the list, since cards don't necessarily return the same
* access point list each scan even if you are standing in the same place.
* Once we have the list, copy in any relevant information from our Allowed list.
*/
dev->options.wireless.ap_list = nm_ap_list_combine (dev->options.wireless.cached_ap_list1, dev->options.wireless.cached_ap_list2);
nm_ap_list_copy_keys (nm_device_ap_list_get (dev), dev->app_data->allowed_ap_list);
/* Generate the "old" list from the 3rd and 4th oldest scans we've done */
old_ap_list = nm_ap_list_combine (dev->options.wireless.cached_ap_list3, dev->options.wireless.cached_ap_list4);
/* Now do a diff of the old and new networks that we can see, and
* signal any changes over dbus, but only if we are active device.
*/
if (dev == data->active_device)
if (dev == dev->app_data->active_device)
nm_ap_list_diff (dev->app_data, dev, old_ap_list, nm_device_ap_list_get (dev));
if (old_ap_list)
nm_ap_list_unref (old_ap_list);
......
......@@ -72,7 +72,7 @@ void nm_device_update_best_ap (NMDevice *dev);
gboolean nm_device_need_ap_switch (NMDevice *dev);
void nm_device_freeze_best_ap (NMDevice *dev);
void nm_device_unfreeze_best_ap (NMDevice *dev);
gboolean nm_device_get_best_ap_frozen (NMDevice *dev);
gboolean nm_device_is_best_ap_frozen (NMDevice *dev);
char * nm_device_get_path_for_ap (NMDevice *dev, NMAccessPoint *ap);
......@@ -81,11 +81,11 @@ void nm_device_set_enc_key (NMDevice *dev, const char *key);
gboolean nm_device_activation_begin (NMDevice *dev);
void nm_device_activation_cancel (NMDevice *dev);
gboolean nm_device_just_activated (NMDevice *dev);
gboolean nm_device_activating (NMDevice *dev);
gboolean nm_device_is_just_activated (NMDevice *dev);
gboolean nm_device_is_activating (NMDevice *dev);
gboolean nm_device_deactivate (NMDevice *dev, gboolean just_added);
gboolean nm_device_now_scanning (NMDevice *dev);
gboolean nm_device_is_scanning (NMDevice *dev);
void nm_device_set_user_key_for_network (NMDevice *dev, struct NMAccessPointList *invalid_list,
unsigned char *network, unsigned char *key,
......
......@@ -277,12 +277,12 @@ gboolean nm_state_modification_monitor (gpointer user_data)
}
else if (best_dev && nm_device_is_wireless (best_dev))
{
if (!nm_device_activating (best_dev) && nm_device_need_ap_switch (best_dev))
if (!nm_device_is_activating (best_dev) && nm_device_need_ap_switch (best_dev))
{
syslog (LOG_INFO, " SWITCH: need to associate with new access point");
do_switch = TRUE;
}
else if (!nm_device_activating (best_dev) && (nm_device_get_ip4_address (best_dev) == 0))
else if (!nm_device_is_activating (best_dev) && (nm_device_get_ip4_address (best_dev) == 0))
{
syslog (LOG_INFO, " SWITCH: need to get an IP address");
do_switch = TRUE;
......@@ -323,7 +323,7 @@ gboolean nm_state_modification_monitor (gpointer user_data)
else
syslog (LOG_ERR, "nm_state_modification_monitor() could not get device list mutex");
}
else if (data->active_device && nm_device_just_activated (data->active_device))
else if (data->active_device && nm_device_is_just_activated (data->active_device))
{
nm_dbus_signal_device_status_change (data->dbus_connection, data->active_device, DEVICE_NOW_ACTIVE);
syslog (LOG_INFO, "nm_state_modification_monitor() activated device %s", nm_device_get_iface (data->active_device));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment