Commit 3ad9d061 authored by Robert Paskowitz's avatar Robert Paskowitz Committed by Dan Williams

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

	* panel-applet/NMWirelessApplet.c
		- Add function to print out applet_state in a readable
			manner

	* src/NetworkManager.c
		- (main): Don't segfault when nm_dbus_init() fails, we had
			a left-over call to hal_shutdown() into which we passed NULL

	* src/NetworkManagerAP.c
		- (nm_ap_set_essid): Allow NULL essids

	* src/NetworkManagerAPList.[ch]
		- More use of nm_ap_list_[un]lock ()
		- (nm_ap_list_get_ap_by_essid): don't warn when looking for a NULL
			network/essid, just return nothing.  Also skip over NULL
			essid access points in the list when searching
		- (nm_ap_list_get_ap_by_address): new function
		- (nm_ap_list_update_network): set the access point's key source to
			NULL when the key returned from NetworkManagerInfo is NULL or
			of 0 length
		- nm_ap_list_update_keys() -> nm_ap_list_update_properties(), and
			copy timestamp over too
		- (nm_ap_list_copy_essids_by_address): new function, attempt to
			find the correct ESSID for a blank-essid access point by searching
			through another list and matching access point MAC addresses
		- (nm_ap_list_diff): exclude blank-essid access points from the diffs

	* src/NetworkManagerDbus.c
		- (nm_dbus_nm_set_active_device): deal with random networks the user
			may specify.  This is mainly for access points that don't
			broadcast their essid.  So if the user tells us to associate with
			some random ESSID that's not in our access point list, we find
			out if the access point does in fact exist (by attempting association
			and then matching that access point's MAC address with the essid the
			user gave us) and then we switch to it.
		- (nm_dbus_devices_handle_request): don't add blank-essid access points
			to the returned list of networks for the "getNetworks" method

	* src/NetworkManagerDevice.[ch]
		- Extra debugging info for link detection
		- (nm_device_ap_list_get_ap_by_address): new function, return an AP
			based on MAC address
		- (nm_device_get_path_for_ap): ignore blank-essid access points
		- (nm_device_wireless_network_exists): new function, find out whether
			a random ESSID exists by attempting to associate with it
		- (nm_device_do_normal_scan): allow blank-essid access points in our
			device list as long as they have an AP MAC address we can use.
			Also send WirelessNetwork[Dis]Appeared signals for non-active
			devices too.  Lets the applet update more frequently.

	* src/backends/NetworkManagerGentoo.c
		- Patch from: Robert Paskowitz
			- Update backend code for Gentoo
			- Implement nm_system_device_update_config_info ()

	* test/nmclienttest.c
		- (set_network_device): new function, takes a command-line argument
			and tells NetworkManager to use that wireless network


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@222 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
parent aea83cfb
2004-10-13 Dan Williams <dcbw@redhat.com>
* panel-applet/NMWirelessApplet.c
- Add function to print out applet_state in a readable
manner
* src/NetworkManager.c
- (main): Don't segfault when nm_dbus_init() fails, we had
a left-over call to hal_shutdown() into which we passed NULL
* src/NetworkManagerAP.c
- (nm_ap_set_essid): Allow NULL essids
* src/NetworkManagerAPList.[ch]
- More use of nm_ap_list_[un]lock ()
- (nm_ap_list_get_ap_by_essid): don't warn when looking for a NULL
network/essid, just return nothing. Also skip over NULL
essid access points in the list when searching
- (nm_ap_list_get_ap_by_address): new function
- (nm_ap_list_update_network): set the access point's key source to
NULL when the key returned from NetworkManagerInfo is NULL or
of 0 length
- nm_ap_list_update_keys() -> nm_ap_list_update_properties(), and
copy timestamp over too
- (nm_ap_list_copy_essids_by_address): new function, attempt to
find the correct ESSID for a blank-essid access point by searching
through another list and matching access point MAC addresses
- (nm_ap_list_diff): exclude blank-essid access points from the diffs
* src/NetworkManagerDbus.c
- (nm_dbus_nm_set_active_device): deal with random networks the user
may specify. This is mainly for access points that don't
broadcast their essid. So if the user tells us to associate with
some random ESSID that's not in our access point list, we find
out if the access point does in fact exist (by attempting association
and then matching that access point's MAC address with the essid the
user gave us) and then we switch to it.
- (nm_dbus_devices_handle_request): don't add blank-essid access points
to the returned list of networks for the "getNetworks" method
* src/NetworkManagerDevice.[ch]
- Extra debugging info for link detection
- (nm_device_ap_list_get_ap_by_address): new function, return an AP
based on MAC address
- (nm_device_get_path_for_ap): ignore blank-essid access points
- (nm_device_wireless_network_exists): new function, find out whether
a random ESSID exists by attempting to associate with it
- (nm_device_do_normal_scan): allow blank-essid access points in our
device list as long as they have an AP MAC address we can use.
Also send WirelessNetwork[Dis]Appeared signals for non-active
devices too. Lets the applet update more frequently.
* src/backends/NetworkManagerGentoo.c
- Patch from: Robert Paskowitz
- Update backend code for Gentoo
- Implement nm_system_device_update_config_info ()
* test/nmclienttest.c
- (set_network_device): new function, takes a command-line argument
and tells NetworkManager to use that wireless network
Wed Oct 13 John (J5) Palmieri <johnp@redhat.com>
* info-daemon/NetworkManagerInfo.c (nmi_spawn_notification_icon): Stop respawning
......
......@@ -142,6 +142,39 @@ animation_timeout (NMWirelessApplet *applet)
return TRUE;
}
inline void print_state (AppletState state)
{
switch (state)
{
case (APPLET_STATE_NO_NM):
g_print ("State: APPLET_STATE_NO_NM\n");
break;
case (APPLET_STATE_NO_CONNECTION):
g_print ("State: APPLET_STATE_NO_CONNECTION\n");
break;
case (APPLET_STATE_WIRED):
g_print ("State: APPLET_STATE_WIRED\n");
break;
case (APPLET_STATE_WIRED_CONNECTING):
g_print ("State: APPLET_STATE_WIRED_CONNECTING\n");
break;
case (APPLET_STATE_WIRELESS):
g_print ("State: APPLET_STATE_WIRELESS\n");
break;
case (APPLET_STATE_WIRELESS_CONNECTING):
g_print ("State: APPLET_STATE_WIRELESS_CONNECTING\n");
break;
case (APPLET_STATE_WIRELESS_SCANNING):
g_print ("State: APPLET_STATE_WIRELESS_SCANNING\n");
break;
default:
g_print ("State: UNKNOWN\n");
break;
}
}
/*
* nmwa_update_state
*
......@@ -183,6 +216,7 @@ nmwa_update_state (NMWirelessApplet *applet)
}
g_mutex_unlock (applet->data_mutex);
/* print_state (applet->applet_state); */
switch (applet->applet_state)
{
case (APPLET_STATE_NO_NM):
......
......@@ -605,7 +605,7 @@ int main( int argc, char *argv[] )
nm_data = nm_data_new (enable_test_devices);
if (!nm_data)
{
syslog( LOG_CRIT, "nm_data_new() failed... Not enough memory?");
syslog (LOG_CRIT, "nm_data_new() failed... Not enough memory?");
exit (EXIT_FAILURE);
}
......@@ -613,8 +613,7 @@ int main( int argc, char *argv[] )
nm_data->dbus_connection = nm_dbus_init (nm_data);
if (!nm_data->dbus_connection)
{
syslog( LOG_CRIT, "nm_dbus_init() failed, exiting");
hal_shutdown (nm_data->hal_ctx);
syslog (LOG_CRIT, "nm_dbus_init() failed, exiting. Either dbus is not running, or the NetworkManager dbus security policy was not loaded.");
nm_data_free (nm_data);
exit (EXIT_FAILURE);
}
......@@ -624,7 +623,7 @@ int main( int argc, char *argv[] )
/* Initialize libhal. We get a connection to the hal daemon here. */
if ((ctx = hal_initialize (&hal_functions, FALSE)) == NULL)
{
syslog( LOG_CRIT, "hal_initialize() failed, exiting... Make sure the hal daemon is running?");
syslog (LOG_CRIT, "hal_initialize() failed, exiting... Make sure the hal daemon is running?");
exit (EXIT_FAILURE);
}
nm_data->hal_ctx = ctx;
......
......@@ -178,9 +178,13 @@ void nm_ap_set_essid (NMAccessPoint *ap, char * essid)
g_return_if_fail (ap != NULL);
if (ap->essid)
{
g_free (ap->essid);
ap->essid = NULL;
}
ap->essid = g_strdup (essid);
if (essid)
ap->essid = g_strdup (essid);
}
......
......@@ -140,7 +140,7 @@ void nm_ap_list_append_ap (NMAccessPointList *list, NMAccessPoint *ap)
g_return_if_fail (list != NULL);
g_return_if_fail (ap != NULL);
if (!nm_try_acquire_mutex (list->mutex, __FUNCTION__))
if (!nm_ap_list_lock (list))
{
syslog( LOG_ERR, "nm_ap_list_append_ap() could not acquire AP list mutex." );
return;
......@@ -149,7 +149,7 @@ void nm_ap_list_append_ap (NMAccessPointList *list, NMAccessPoint *ap)
nm_ap_ref (ap);
list->ap_list = g_slist_append (list->ap_list, ap);
nm_unlock_mutex (list->mutex, __FUNCTION__);
nm_ap_list_unlock (list);
}
......@@ -166,7 +166,7 @@ void nm_ap_list_remove_ap (NMAccessPointList *list, NMAccessPoint *ap)
g_return_if_fail (list != NULL);
g_return_if_fail (ap != NULL);
if (!nm_try_acquire_mutex (list->mutex, __FUNCTION__))
if (!nm_ap_list_lock (list))
{
syslog( LOG_ERR, "nm_ap_list_append_ap() could not acquire AP list mutex." );
return;
......@@ -186,8 +186,7 @@ void nm_ap_list_remove_ap (NMAccessPointList *list, NMAccessPoint *ap)
}
element = g_slist_next (element);
}
nm_unlock_mutex (list->mutex, __FUNCTION__);
nm_ap_list_unlock (list);
}
......@@ -204,7 +203,8 @@ NMAccessPoint *nm_ap_list_get_ap_by_essid (NMAccessPointList *list, const char *
NMAccessPoint *found_ap = NULL;
NMAPListIter *iter;
g_return_val_if_fail (network != NULL, NULL);
if (!network)
return (NULL);
if (!list)
return (NULL);
......@@ -214,14 +214,50 @@ NMAccessPoint *nm_ap_list_get_ap_by_essid (NMAccessPointList *list, const char *
while ((ap = nm_ap_list_iter_next (iter)))
{
if (nm_null_safe_strcmp (nm_ap_get_essid (ap), network) == 0)
if (nm_ap_get_essid (ap) && (nm_null_safe_strcmp (nm_ap_get_essid (ap), network) == 0))
{
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)))
{
if (nm_ap_get_address (ap) && (memcmp (addr, nm_ap_get_address (ap), sizeof (struct ether_addr)) == 0))
{
found_ap = ap;
break;
}
}
nm_ap_list_iter_free (iter);
return (found_ap);
}
......@@ -258,7 +294,10 @@ void nm_ap_list_update_network (NMAccessPointList *list, const char *network, NM
nm_ap_set_essid (ap, essid);
nm_ap_set_timestamp (ap, timestamp);
nm_ap_set_trusted (ap, trusted);
nm_ap_set_enc_key_source (ap, key, enc_method);
if (key && strlen (key))
nm_ap_set_enc_key_source (ap, key, enc_method);
else
nm_ap_set_enc_key_source (ap, NULL, NM_AP_ENC_METHOD_UNKNOWN);
}
g_free (timestamp);
......@@ -360,14 +399,14 @@ NMAccessPointList * nm_ap_list_combine (NMAccessPointList *list1, NMAccessPointL
/*
* nm_ap_list_copy_keys
* nm_ap_list_copy_properties
*
* Update the keys and encryption methods in one access point list from
* 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_keys (NMAccessPointList *dest, NMAccessPointList *source)
void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *source)
{
NMAPListIter *iter;
NMAccessPoint *dest_ap;
......@@ -385,6 +424,40 @@ void nm_ap_list_copy_keys (NMAccessPointList *dest, NMAccessPointList *source)
{
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_set_timestamp (dest_ap, nm_ap_get_timestamp (src_ap));
}
}
nm_ap_list_iter_free (iter);
}
}
/*
* nm_ap_list_copy_essids_by_address
*
* For each blank-essid 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 essid to the dest access point.
*
*/
void nm_ap_list_copy_essids_by_address (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 (!nm_ap_get_essid (dest_ap) && (src_ap = nm_ap_list_get_ap_by_address (source, nm_ap_get_address (dest_ap))))
{
if (nm_ap_get_essid (src_ap))
nm_ap_set_essid (dest_ap, nm_ap_get_essid (src_ap));
}
}
nm_ap_list_iter_free (iter);
......@@ -424,13 +497,16 @@ void nm_ap_list_diff (NMData *data, NMDevice *dev, NMAccessPointList *old, NMAcc
{
NMAccessPoint *new_ap = NULL;
if ((new_ap = nm_ap_list_get_ap_by_essid (new, nm_ap_get_essid (old_ap))))
if (nm_ap_get_essid (old_ap))
{
nm_ap_set_matched (old_ap, TRUE);
nm_ap_set_matched (new_ap, TRUE);
if ((new_ap = nm_ap_list_get_ap_by_essid (new, nm_ap_get_essid (old_ap))))
{
nm_ap_set_matched (old_ap, TRUE);
nm_ap_set_matched (new_ap, TRUE);
}
else
nm_dbus_signal_wireless_network_change (data->dbus_connection, dev, old_ap, TRUE);
}
else
nm_dbus_signal_wireless_network_change (data->dbus_connection, dev, old_ap, TRUE);
}
nm_ap_list_iter_free (iter);
}
......@@ -442,7 +518,7 @@ void nm_ap_list_diff (NMData *data, NMDevice *dev, NMAccessPointList *old, NMAcc
{
while ((new_ap = nm_ap_list_iter_next (iter)))
{
if (!nm_ap_get_matched (new_ap))
if (!nm_ap_get_matched (new_ap) && nm_ap_get_essid (new_ap))
nm_dbus_signal_wireless_network_change (data->dbus_connection, dev, new_ap, FALSE);
}
nm_ap_list_iter_free (iter);
......
......@@ -47,12 +47,14 @@ void nm_ap_list_append_ap (NMAccessPointList *list, NMAccessPoint *ap);
void nm_ap_list_remove_ap (NMAccessPointList *list, NMAccessPoint *ap);
NMAccessPoint * nm_ap_list_get_ap_by_essid (NMAccessPointList *list, const char *network);
NMAccessPoint * nm_ap_list_get_ap_by_address (NMAccessPointList *list, const struct ether_addr *addr);
void nm_ap_list_update_network (NMAccessPointList *list, const char *network, NMData *data);
void nm_ap_list_populate (NMAccessPointList *list, NMData *data);
void nm_ap_list_copy_keys (NMAccessPointList *dest, NMAccessPointList *source);
void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *source);
void nm_ap_list_copy_essids_by_address (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);
......
......@@ -253,9 +253,9 @@ static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DB
reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "InvalidArguments",
"NetworkManager::setActiveDevice called with invalid arguments.");
return (reply_message);
} else fprintf (stderr, "FORCE: device '%s'\n", dev_path);
} else syslog (LOG_INFO, "FORCE: device '%s'", dev_path);
}
else fprintf (stderr, "FORCE: device '%s', network '%s'\n", dev_path, network);
else syslog (LOG_INFO, "FORCE: device '%s', network '%s'", dev_path, network);
/* So by now we have a valid device and possibly a network as well */
......@@ -286,12 +286,35 @@ static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DB
NMAccessPoint *ap;
if ((ap = nm_ap_list_get_ap_by_essid (nm_device_ap_list_get (dev), network)))
{
syslog (LOG_DEBUG, "Forcing AP '%s'", nm_ap_get_essid (ap));
else
{
struct ether_addr ap_addr;
syslog (LOG_DEBUG, "Forcing non-scanned AP '%s'", network);
/* If the network exists, make sure it has the correct ESSID set
* (it might have been a blank ESSID up to this point) and use it.
*/
nm_device_deactivate (dev, FALSE);
if (nm_device_wireless_network_exists (dev, network, &ap_addr))
{
if ((ap = nm_device_ap_list_get_ap_by_address (dev, &ap_addr)))
nm_ap_set_essid (ap, network);
}
}
/* If we found a valid access point, use it */
if (ap)
{
nm_device_set_best_ap (dev, ap);
nm_device_freeze_best_ap (dev);
nm_device_activation_cancel (dev);
}
else
{
reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NetworkNotFound",
"The requested wireless network is not in range.");
}
}
dbus_free (network);
......@@ -1170,11 +1193,14 @@ static DBusMessage *nm_dbus_devices_handle_request (DBusConnection *connection,
{
while ((ap = nm_ap_list_iter_next (list_iter)))
{
object_path = g_strdup_printf ("%s/%s/Networks/%s", NM_DBUS_PATH_DEVICES,
nm_device_get_iface (dev), nm_ap_get_essid (ap));
dbus_message_iter_append_string (&iter_array, object_path);
g_free (object_path);
success = TRUE;
if (nm_ap_get_essid (ap))
{
object_path = g_strdup_printf ("%s/%s/Networks/%s", NM_DBUS_PATH_DEVICES,
nm_device_get_iface (dev), nm_ap_get_essid (ap));
dbus_message_iter_append_string (&iter_array, object_path);
g_free (object_path);
success = TRUE;
}
}
nm_ap_list_iter_free (list_iter);
}
......@@ -1449,19 +1475,22 @@ DBusConnection *nm_dbus_init (NMData *data)
success = dbus_connection_register_object_path (connection, NM_DBUS_PATH, &nm_vtable, data);
if (!success)
{
syslog (LOG_ERR, "nm_dbus_init() could not register a handler for NetworkManager. Not enough memory?");
syslog (LOG_CRIT, "nm_dbus_init() could not register a handler for NetworkManager. Not enough memory?");
return (NULL);
}
success = dbus_connection_register_fallback (connection, NM_DBUS_PATH_DEVICES, &devices_vtable, data);
if (!success)
{
syslog (LOG_ERR, "nm_dbus_init() could not register a handler for NetworkManager devices. Not enough memory?");
syslog (LOG_CRIT, "nm_dbus_init() could not register a handler for NetworkManager devices. Not enough memory?");
return (NULL);
}
if (!dbus_connection_add_filter (connection, nm_dbus_nmi_filter, data, NULL))
{
syslog (LOG_CRIT, "nm_dbus_init() could not attach a dbus message filter. The NetworkManager dbus security policy may not be loaded. Restart dbus?");
return (NULL);
}
dbus_bus_add_match (connection,
"type='signal',"
......
......@@ -1298,6 +1298,7 @@ inline gboolean HAVE_LINK (NMDevice *dev, guint32 bad_crypt_packets)
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (nm_device_is_wireless (dev), FALSE);
fprintf (stderr, "HAVELINK: act=%d && (dev_crypt=%d <= prev_crypt=%d)\n", nm_device_get_link_active (dev), nm_device_get_bad_crypt_packets (dev), bad_crypt_packets);
return (nm_device_get_link_active (dev) && (nm_device_get_bad_crypt_packets (dev) <= bad_crypt_packets));
}
......@@ -1367,6 +1368,9 @@ void nm_device_activate_wireless_wait_for_link (NMDevice *dev)
|| (best_ap && (nm_ap_get_encrypted (best_ap) &&
(!nm_ap_get_enc_key_source (best_ap) || !strlen (nm_ap_get_enc_key_source (best_ap))))))
{
fprintf (stderr, "LINK: !HAVE=%d, (best_ap=0x%X && (is_enc=%d && (!source=%d || !len_source=%d)))\n",
!HAVE_LINK (dev, bad_crypt_packets), best_ap, nm_ap_get_encrypted (best_ap), !nm_ap_get_enc_key_source (best_ap),
nm_ap_get_enc_key_source (best_ap) ? !strlen (nm_ap_get_enc_key_source (best_ap)) : 0);
if ((best_ap = nm_device_get_best_ap (dev)))
{
dev->options.wireless.now_scanning = FALSE;
......@@ -1755,6 +1759,29 @@ NMAccessPoint *nm_device_ap_list_get_ap_by_essid (NMDevice *dev, const char *ess
}
/*
* nm_device_ap_list_get_ap_by_address
*
* Get the access point for a specific MAC address
*
*/
NMAccessPoint *nm_device_ap_list_get_ap_by_address (NMDevice *dev, const struct ether_addr *addr)
{
NMAccessPoint *ret_ap = NULL;
g_return_val_if_fail (dev != NULL, NULL);
g_return_val_if_fail (nm_device_is_wireless (dev), NULL);
g_return_val_if_fail (addr != NULL, NULL);
if (!dev->options.wireless.ap_list)
return (NULL);
ret_ap = nm_ap_list_get_ap_by_address (dev->options.wireless.ap_list, addr);
return (ret_ap);
}
/*
* nm_device_ap_list_get
*
......@@ -1851,7 +1878,10 @@ char * nm_device_get_path_for_ap (NMDevice *dev, NMAccessPoint *ap)
g_return_val_if_fail (dev != NULL, NULL);
g_return_val_if_fail (ap != NULL, NULL);
return (g_strdup_printf ("%s/%s/Networks/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev), nm_ap_get_essid (ap)));
if (nm_ap_get_essid (ap))
return (g_strdup_printf ("%s/%s/Networks/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev), nm_ap_get_essid (ap)));
else
return (NULL);
}
......@@ -1977,6 +2007,59 @@ void nm_device_update_best_ap (NMDevice *dev)
}
/*
* nm_device_wireless_network_exists
*
* Tell the card to explicitly use with a particular essid, and then
* see if we can associate with some AP using that ESSID.
* Mainly for non-essid-broadcasting APs to figure out whether or not
* some random ESSID the user gave us exists or not.
*
* WARNING: will blow away any connection the card currently has.
*
*/
gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network, struct ether_addr *ap_addr)
{
struct ether_addr addr;
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (network != NULL, FALSE);
g_return_val_if_fail (ap_addr != NULL, FALSE);
g_return_val_if_fail (strlen (network), FALSE);
fprintf (stderr, "nm_device_wireless_network_exists () looking for network '%s'...", network);
nm_device_bring_down (dev);
/* Force the card into Managed/Infrastructure mode */
nm_device_set_mode_managed (dev);
/* Disable encryption, then re-enable and set correct key on the card
* if we are going to encrypt traffic.
*/
nm_device_set_enc_key (dev, NULL);
nm_device_set_essid (dev, network);
/* Bring the device up and pause to allow card to associate */
nm_device_bring_up (dev);
g_usleep (G_USEC_PER_SEC * 2);
nm_device_update_link_active (dev, FALSE);
nm_device_get_ap_address (dev, &addr);
if (nm_ethernet_address_is_valid (&addr) && nm_device_get_essid (dev))
{
nm_device_get_ap_address (dev, ap_addr);
fprintf (stderr, " found!\n");
return (TRUE);
}
else
{
fprintf (stderr, " not found\n");
return (FALSE);
}
}
/*
* nm_device_do_normal_scan
*
......@@ -2009,6 +2092,7 @@ static void nm_device_do_normal_scan (NMDevice *dev)
int err;
NMAccessPointList *old_ap_list = NULL;
NMAccessPointList *temp_list;
gboolean have_blank_essids = FALSE;
err = iw_scan (iwlib_socket, nm_device_get_iface (dev), WIRELESS_EXT, &scan_results);
if ((err == -1) && (errno == ENODATA))
......@@ -2047,16 +2131,19 @@ static void nm_device_do_normal_scan (NMDevice *dev)
tmp_ap = scan_results.result;
while (tmp_ap)
{
/* Blank essids usually indicate an AP that is not broadcasting its essid,
* but since its not broadcasting the essid, we cannot use that ap yet.
*/
if (tmp_ap->b.has_essid && tmp_ap->b.essid_on && (strlen (tmp_ap->b.essid) > 0))
/* We need at least an ESSID or a MAC address for each access point */
if (tmp_ap->b.has_essid || tmp_ap->has_ap_addr)
{
NMAccessPoint *nm_ap = nm_ap_new ();
NMAccessPoint *list_ap;
/* Copy over info from scan to local structure */
nm_ap_set_essid (nm_ap, tmp_ap->b.essid);
if (!tmp_ap->b.has_essid || (tmp_ap->b.essid && !strlen (tmp_ap->b.essid)))
{
nm_ap_set_essid (nm_ap, NULL);
have_blank_essids = TRUE;
}
else
nm_ap_set_essid (nm_ap, tmp_ap->b.essid);
if (tmp_ap->b.has_key && (tmp_ap->b.key_flags & IW_ENCODE_DISABLED))
nm_ap_set_encrypted (nm_ap, FALSE);
......@@ -2071,12 +2158,6 @@ 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 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_ap_list_append_ap (dev->options.wireless.cached_ap_list1, nm_ap);
}
......@@ -2085,17 +2166,24 @@ static void nm_device_do_normal_scan (NMDevice *dev)
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.
*/
old_ap_list = nm_device_ap_list_get (dev);
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);
nm_ap_list_copy_properties (nm_device_ap_list_get (dev), dev->app_data->allowed_ap_list);
/* If any blank ESSID networks were detected in the current scan, try to match their
* AP MAC address with existing ones in previous scans, and if we get a match, copy the
* ESSID over to the newest scan list. This enures that we keep the known ESSID for that
* base station around as long as possible, which allows nm_device_update_best_ap() to do
* its job when the user wanted us to connect to a non-broadcasting network.
*/
if (have_blank_essids)
nm_ap_list_copy_essids_by_address (nm_device_ap_list_get (dev), old_ap_list);
nm_ap_list_unref (old_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);
......@@ -2103,8 +2191,7 @@ static void nm_device_do_normal_scan (NMDevice *dev)
/* 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 == dev->app_data->active_device)
nm_ap_list_diff (dev->app_data, dev, old_ap_list, nm_device_ap_list_get (dev));
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);
}
......
......@@ -59,6 +59,7 @@ void nm_device_get_ip6_address (NMDevice *dev);
gboolean nm_device_get_supports_wireless_scan (NMDevice *dev);
void nm_device_do_wireless_scan (NMDevice *dev);
gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network, struct ether_addr *addr);
void nm_device_set_mode_managed (NMDevice *dev);
void nm_device_set_mode_adhoc (NMDevice *dev);
......@@ -101,6 +102,7 @@ gboolean nm_device_is_up (NMDevice *dev);
void nm_device_ap_list_clear (NMDevice *dev);
struct NMAccessPointList *nm_device_ap_list_get (NMDevice *dev);
NMAccessPoint *nm_device_ap_list_get_ap_by_essid (NMDevice *dev, const char *essid);
NMAccessPoint *nm_device_ap_list_get_ap_by_address(NMDevice *dev, const struct ether_addr *addr);
/* System config data accessors */
gboolean nm_device_config_get_use_dhcp (NMDevice *dev);
......
......@@ -30,7 +30,7 @@
#include "NetworkManagerUtils.h"