mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-25 09:30:16 +01:00
* Finally move info-daemon related stuff out of NetworkManagerDbus.c to nm-dbus-nmi.c git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1201 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
675 lines
19 KiB
C
675 lines
19 KiB
C
/* NetworkManager -- Network link manager
|
|
*
|
|
* Dan Williams <dcbw@redhat.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* (C) Copyright 2005 Red Hat, Inc.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <signal.h>
|
|
#include <fcntl.h>
|
|
#include <sys/select.h>
|
|
|
|
#include "NetworkManagerPolicy.h"
|
|
#include "NetworkManagerUtils.h"
|
|
#include "NetworkManagerAP.h"
|
|
#include "NetworkManagerAPList.h"
|
|
#include "NetworkManagerDbus.h"
|
|
#include "nm-activation-request.h"
|
|
#include "nm-utils.h"
|
|
#include "nm-dbus-nmi.h"
|
|
|
|
|
|
/*
|
|
* nm_policy_activation_finish
|
|
*
|
|
* Finishes up activation by sending out dbus signals, which has to happen
|
|
* on the main thread.
|
|
*
|
|
*/
|
|
static gboolean nm_policy_activation_finish (NMActRequest *req)
|
|
{
|
|
NMDevice *dev = NULL;
|
|
NMData *data = NULL;
|
|
|
|
g_return_val_if_fail (req != NULL, FALSE);
|
|
|
|
data = nm_act_request_get_data (req);
|
|
g_assert (data);
|
|
|
|
dev = nm_act_request_get_dev (req);
|
|
g_assert (dev);
|
|
|
|
/* Tell NetworkManagerInfo to store the MAC address of the active device's AP */
|
|
if (nm_device_is_802_11_wireless (dev))
|
|
{
|
|
struct ether_addr addr;
|
|
NMAccessPoint * ap = nm_act_request_get_ap (req);
|
|
NMAccessPoint * tmp_ap;
|
|
|
|
/* Cache details in the info-daemon since the connect was successful */
|
|
nm_dbus_update_network_info (data->dbus_connection, ap, nm_act_request_get_user_requested (req));
|
|
|
|
nm_device_get_ap_address (dev, &addr);
|
|
if (!nm_ap_get_address (ap) || !nm_ethernet_address_is_valid (nm_ap_get_address (ap)))
|
|
nm_ap_set_address (ap, &addr);
|
|
|
|
/* Don't store MAC addresses for non-infrastructure networks */
|
|
if ((nm_ap_get_mode (ap) == IW_MODE_INFRA) && nm_ethernet_address_is_valid (&addr))
|
|
nm_dbus_add_network_address (data->dbus_connection, NETWORK_TYPE_ALLOWED, nm_ap_get_essid (ap), &addr);
|
|
}
|
|
|
|
nm_info ("Activation (%s) successful, device activated.", nm_device_get_iface (dev));
|
|
nm_dbus_schedule_device_status_change_signal (data, dev, NULL, DEVICE_NOW_ACTIVE);
|
|
nm_schedule_state_change_signal_broadcast (data);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* nm_policy_schedule_activation_finish
|
|
*
|
|
*/
|
|
void nm_policy_schedule_activation_finish (NMActRequest *req)
|
|
{
|
|
GSource * source;
|
|
NMData * data;
|
|
NMDevice * dev;
|
|
|
|
g_return_if_fail (req != NULL);
|
|
|
|
data = nm_act_request_get_data (req);
|
|
g_assert (data);
|
|
|
|
dev = nm_act_request_get_dev (req);
|
|
g_assert (dev);
|
|
|
|
nm_act_request_set_stage (req, NM_ACT_STAGE_ACTIVATED);
|
|
|
|
source = g_idle_source_new ();
|
|
g_source_set_priority (source, G_PRIORITY_HIGH_IDLE);
|
|
g_source_set_callback (source, (GSourceFunc) nm_policy_activation_finish, req, NULL);
|
|
g_source_attach (source, data->main_context);
|
|
g_source_unref (source);
|
|
nm_info ("Activation (%s) Finish handler scheduled.", nm_device_get_iface (dev));
|
|
}
|
|
|
|
|
|
/*
|
|
* nm_policy_activation_failed
|
|
*
|
|
* Clean up a failed activation.
|
|
*
|
|
*/
|
|
static gboolean nm_policy_activation_failed (NMActRequest *req)
|
|
{
|
|
NMDevice *dev = NULL;
|
|
NMAccessPoint *ap = NULL;
|
|
NMData *data = NULL;
|
|
|
|
g_return_val_if_fail (req != NULL, FALSE);
|
|
|
|
data = nm_act_request_get_data (req);
|
|
g_assert (data);
|
|
|
|
dev = nm_act_request_get_dev (req);
|
|
g_assert (dev);
|
|
|
|
if (nm_device_is_802_11_wireless (dev))
|
|
{
|
|
if ((ap = nm_act_request_get_ap (req)))
|
|
{
|
|
/* Only pop up the Network Not Found dialog when its a user-requested access point
|
|
* that failed, not one that we've automatically found and connected to.
|
|
*/
|
|
if (nm_act_request_get_user_requested (req))
|
|
nm_dbus_schedule_device_status_change_signal (data, dev, ap, DEVICE_ACTIVATION_FAILED);
|
|
|
|
/* Add the AP to the invalid list and force a best ap update */
|
|
nm_ap_set_invalid (ap, TRUE);
|
|
nm_ap_list_append_ap (data->invalid_ap_list, ap);
|
|
}
|
|
|
|
nm_info ("Activation (%s) failed for access point (%s)", nm_device_get_iface (dev),
|
|
ap ? nm_ap_get_essid (ap) : "(none)");
|
|
}
|
|
else
|
|
{
|
|
nm_info ("Activation (%s) failed.", nm_device_get_iface (dev));
|
|
nm_dbus_schedule_device_status_change_signal (data, dev, NULL, DEVICE_ACTIVATION_FAILED);
|
|
}
|
|
|
|
nm_device_deactivate (dev);
|
|
nm_schedule_state_change_signal_broadcast (data);
|
|
nm_policy_schedule_device_change_check (data);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* nm_policy_schedule_activation_failed
|
|
*
|
|
*/
|
|
void nm_policy_schedule_activation_failed (NMActRequest *req)
|
|
{
|
|
GSource * source;
|
|
NMData * data;
|
|
NMDevice * dev;
|
|
|
|
g_return_if_fail (req != NULL);
|
|
|
|
data = nm_act_request_get_data (req);
|
|
g_assert (data);
|
|
|
|
dev = nm_act_request_get_dev (req);
|
|
g_assert (dev);
|
|
|
|
nm_act_request_set_stage (req, NM_ACT_STAGE_FAILED);
|
|
|
|
source = g_idle_source_new ();
|
|
g_source_set_priority (source, G_PRIORITY_HIGH_IDLE);
|
|
g_source_set_callback (source, (GSourceFunc) nm_policy_activation_failed, req, NULL);
|
|
g_source_attach (source, data->main_context);
|
|
g_source_unref (source);
|
|
nm_info ("Activation (%s) failure scheduled...", nm_device_get_iface (dev));
|
|
}
|
|
|
|
|
|
/*
|
|
* nm_policy_auto_get_best_device
|
|
*
|
|
* Find the best device to use, regardless of whether we are
|
|
* "locked" on one device at this time.
|
|
*
|
|
*/
|
|
static NMDevice * nm_policy_auto_get_best_device (NMData *data, NMAccessPoint **ap)
|
|
{
|
|
GSList *elt;
|
|
NMDevice *best_wired_dev = NULL;
|
|
guint best_wired_prio = 0;
|
|
NMDevice *best_wireless_dev = NULL;
|
|
guint best_wireless_prio = 0;
|
|
NMDevice *highest_priority_dev = NULL;
|
|
|
|
g_return_val_if_fail (data != NULL, NULL);
|
|
g_return_val_if_fail (ap != NULL, NULL);
|
|
|
|
if (data->asleep)
|
|
return NULL;
|
|
|
|
for (elt = data->dev_list; elt != NULL; elt = g_slist_next (elt))
|
|
{
|
|
guint dev_type;
|
|
gboolean link_active;
|
|
guint prio = 0;
|
|
NMDevice * dev = (NMDevice *)(elt->data);
|
|
guint32 caps;
|
|
|
|
dev_type = nm_device_get_type (dev);
|
|
link_active = nm_device_has_active_link (dev);
|
|
caps = nm_device_get_capabilities (dev);
|
|
|
|
/* Don't use devices that SUCK */
|
|
if (!(caps & NM_DEVICE_CAP_NM_SUPPORTED))
|
|
continue;
|
|
|
|
if (nm_device_is_802_3_ethernet (dev))
|
|
{
|
|
/* We never automatically choose devices that don't support carrier detect */
|
|
if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT))
|
|
continue;
|
|
|
|
if (link_active)
|
|
prio += 1;
|
|
|
|
if (nm_device_get_act_request (dev) && link_active)
|
|
prio += 1;
|
|
|
|
if (prio > best_wired_prio)
|
|
{
|
|
best_wired_dev = dev;
|
|
best_wired_prio = prio;
|
|
}
|
|
}
|
|
else if (nm_device_is_802_11_wireless (dev) && data->wireless_enabled)
|
|
{
|
|
/* Don't automatically choose a device that doesn't support wireless scanning */
|
|
if (!(caps & NM_DEVICE_CAP_WIRELESS_SCAN))
|
|
continue;
|
|
|
|
/* Bump by 1 so that _something_ gets chosen every time */
|
|
prio += 1;
|
|
|
|
if (link_active)
|
|
prio += 1;
|
|
|
|
if (nm_device_get_act_request (dev) && link_active)
|
|
prio += 3;
|
|
|
|
if (prio > best_wireless_prio)
|
|
{
|
|
best_wireless_dev = dev;
|
|
best_wireless_prio = prio;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (best_wired_dev)
|
|
highest_priority_dev = best_wired_dev;
|
|
else if (best_wireless_dev)
|
|
{
|
|
highest_priority_dev = best_wireless_dev;
|
|
*ap = nm_device_get_best_ap (highest_priority_dev);
|
|
/* If the device doesn't have a "best" ap, then we can't use it */
|
|
if (!*ap)
|
|
highest_priority_dev = NULL;
|
|
}
|
|
|
|
#if 0
|
|
nm_info ("AUTO: Best wired device = %s, best wireless device = %s (%s)", best_wired_dev ? nm_device_get_iface (best_wired_dev) : "(null)",
|
|
best_wireless_dev ? nm_device_get_iface (best_wireless_dev) : "(null)", (best_wireless_dev && *ap) ? nm_ap_get_essid (*ap) : "null" );
|
|
#endif
|
|
|
|
return highest_priority_dev;
|
|
}
|
|
|
|
|
|
/*
|
|
* nm_policy_device_change_check
|
|
*
|
|
* Figures out which interface to switch the active
|
|
* network connection to if our global network state has changed.
|
|
* Global network state changes are triggered by:
|
|
* 1) insertion/deletion of interfaces
|
|
* 2) link state change of an interface
|
|
* 3) wireless network topology changes
|
|
*
|
|
*/
|
|
static gboolean nm_policy_device_change_check (NMData *data)
|
|
{
|
|
NMAccessPoint * ap = NULL;
|
|
NMDevice * new_dev = NULL;
|
|
NMDevice * old_dev = NULL;
|
|
gboolean do_switch = FALSE;
|
|
|
|
g_return_val_if_fail (data != NULL, FALSE);
|
|
|
|
data->dev_change_check_idle_id = 0;
|
|
|
|
old_dev = nm_get_active_device (data);
|
|
|
|
if (!nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__))
|
|
return FALSE;
|
|
|
|
if (old_dev)
|
|
{
|
|
guint32 caps = nm_device_get_capabilities (old_dev);
|
|
|
|
/* Don't interrupt a currently activating device. */
|
|
if (nm_device_is_activating (old_dev))
|
|
{
|
|
nm_info ("Old device '%s' activating, won't change.", nm_device_get_iface (old_dev));
|
|
goto out;
|
|
}
|
|
|
|
/* Don't interrupt semi-supported devices either. If the user chose one, they must
|
|
* explicitly choose to move to another device, we're not going to move for them.
|
|
*/
|
|
if ((nm_device_is_802_3_ethernet (old_dev) && !(caps & NM_DEVICE_CAP_CARRIER_DETECT))
|
|
|| (nm_device_is_802_11_wireless (old_dev) && !(caps & NM_DEVICE_CAP_WIRELESS_SCAN)))
|
|
{
|
|
nm_info ("Old device '%s' was semi-supported and user chosen, won't change unless told to.",
|
|
nm_device_get_iface (old_dev));
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
new_dev = nm_policy_auto_get_best_device (data, &ap);
|
|
|
|
/* Four cases here:
|
|
*
|
|
* 1) old device is NULL, new device is NULL - we aren't currently connected to anything, and we
|
|
* can't find anything to connect to. Do nothing.
|
|
*
|
|
* 2) old device is NULL, new device is good - we aren't currenlty connected to anything, but
|
|
* we have something we can connect to. Connect to it.
|
|
*
|
|
* 3) old device is good, new device is NULL - have a current connection, but it's no good since
|
|
* auto device picking didn't come up with the save device. Terminate current connection.
|
|
*
|
|
* 4) old device is good, new device is good - have a current connection, and auto device picking
|
|
* came up with a device too. More considerations:
|
|
* a) different devices? activate new device
|
|
* b) same device, different access points? activate new device
|
|
* c) same device, same access point? do nothing
|
|
*/
|
|
|
|
if (!old_dev && !new_dev)
|
|
{
|
|
/* Do nothing, wait for something like link-state to change, or an access point to be found */
|
|
}
|
|
else if (!old_dev && new_dev)
|
|
{
|
|
/* Activate new device */
|
|
nm_info ("SWITCH: no current connection, found better connection '%s'.", nm_device_get_iface (new_dev));
|
|
do_switch = TRUE;
|
|
}
|
|
else if (old_dev && !new_dev)
|
|
{
|
|
/* Terminate current connection */
|
|
nm_info ("SWITCH: terminating current connection '%s' because it's no longer valid.", nm_device_get_iface (old_dev));
|
|
nm_device_deactivate (old_dev);
|
|
do_switch = TRUE;
|
|
}
|
|
else if (old_dev && new_dev)
|
|
{
|
|
NMActRequest * old_act_req = nm_device_get_act_request (old_dev);
|
|
gboolean old_user_requested = nm_act_request_get_user_requested (old_act_req);
|
|
|
|
if (nm_device_is_802_3_ethernet (old_dev))
|
|
{
|
|
/* Only switch if the old device was not user requested, and we are either switching to
|
|
* a new device. Note that new_dev will never be wireless since automatic device picking
|
|
* above will prefer a wired device to a wireless device.
|
|
*/
|
|
if (!old_user_requested && (new_dev != old_dev))
|
|
{
|
|
nm_info ("SWITCH: found better connection '%s' than current connection '%s'.", nm_device_get_iface (new_dev), nm_device_get_iface (old_dev));
|
|
do_switch = TRUE;
|
|
}
|
|
}
|
|
else if (nm_device_is_802_11_wireless (old_dev))
|
|
{
|
|
/* Only switch if the old device's wireless config is invalid */
|
|
if (nm_device_is_802_11_wireless (new_dev))
|
|
{
|
|
NMAccessPoint *old_ap = nm_act_request_get_ap (old_act_req);
|
|
const char * old_essid = nm_ap_get_essid (old_ap);
|
|
const char * new_essid = nm_ap_get_essid (ap);
|
|
|
|
/* Schedule new activation if the currently associated access point is not the "best" one
|
|
* or we've lost the link to the old access point.
|
|
*/
|
|
gboolean es = (strcmp (old_essid, new_essid) != 0);
|
|
gboolean link = nm_device_has_active_link (old_dev);
|
|
if (es || !link)
|
|
{
|
|
nm_info ("SWITCH: found better connection '%s/%s' than current connection '%s/%s'. different_ssids=%d, have_link=%d",
|
|
nm_device_get_iface (new_dev), new_essid,
|
|
nm_device_get_iface (old_dev), old_essid,
|
|
es, link);
|
|
do_switch = TRUE;
|
|
}
|
|
}
|
|
else if (nm_device_is_802_3_ethernet (new_dev))
|
|
{
|
|
if (!nm_device_has_active_link (old_dev))
|
|
do_switch = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (do_switch && (nm_device_is_802_3_ethernet (new_dev) || (nm_device_is_802_11_wireless (new_dev) && ap)))
|
|
{
|
|
NMActRequest * act_req = NULL;
|
|
|
|
if ((act_req = nm_act_request_new (data, new_dev, ap, FALSE)))
|
|
|
|
{
|
|
nm_info ("Will activate connection '%s%s%s'.", nm_device_get_iface (new_dev), ap ? "/" : "", ap ? nm_ap_get_essid (ap) : "");
|
|
nm_policy_schedule_device_activation (act_req);
|
|
}
|
|
}
|
|
|
|
if (ap)
|
|
nm_ap_unref (ap);
|
|
|
|
out:
|
|
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* nm_policy_schedule_device_change_check
|
|
*
|
|
* Queue up an idle handler to deal with state changes that could
|
|
* cause us to activate a different device or wireless network.
|
|
*
|
|
*/
|
|
void nm_policy_schedule_device_change_check (NMData *data)
|
|
{
|
|
static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
|
|
|
|
g_return_if_fail (data != NULL);
|
|
|
|
g_static_mutex_lock (&mutex);
|
|
|
|
if (data->dev_change_check_idle_id == 0)
|
|
{
|
|
GSource * source = g_idle_source_new ();
|
|
|
|
g_source_set_callback (source, (GSourceFunc) nm_policy_device_change_check, data, NULL);
|
|
data->dev_change_check_idle_id = g_source_attach (source, data->main_context);
|
|
g_source_unref (source);
|
|
}
|
|
|
|
g_static_mutex_unlock (&mutex);
|
|
}
|
|
|
|
|
|
/*
|
|
* nm_policy_device_activation
|
|
*
|
|
* Handle device activation, shutting down all other devices and starting
|
|
* activation on the requested device.
|
|
*
|
|
*/
|
|
static gboolean nm_policy_device_activation (NMActRequest *req)
|
|
{
|
|
NMData * data;
|
|
NMDevice * new_dev = NULL;
|
|
NMDevice * old_dev = NULL;
|
|
|
|
g_return_val_if_fail (req != NULL, FALSE);
|
|
|
|
data = nm_act_request_get_data (req);
|
|
g_assert (data);
|
|
|
|
if ((old_dev = nm_get_active_device (data)))
|
|
nm_device_deactivate (old_dev);
|
|
|
|
new_dev = nm_act_request_get_dev (req);
|
|
if (nm_device_is_activating (new_dev))
|
|
return FALSE;
|
|
|
|
nm_device_activation_start (req);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* nm_policy_schedule_device_activation
|
|
*
|
|
* Activate a particular device (and possibly access point)
|
|
*
|
|
*/
|
|
void nm_policy_schedule_device_activation (NMActRequest *req)
|
|
{
|
|
GSource * source;
|
|
NMData * data;
|
|
NMDevice * dev;
|
|
|
|
g_return_if_fail (req != NULL);
|
|
|
|
data = nm_act_request_get_data (req);
|
|
g_assert (data);
|
|
|
|
dev = nm_act_request_get_dev (req);
|
|
g_assert (dev);
|
|
|
|
source = g_idle_source_new ();
|
|
g_source_set_priority (source, G_PRIORITY_HIGH_IDLE);
|
|
g_source_set_callback (source, (GSourceFunc) nm_policy_device_activation, req, NULL);
|
|
g_source_attach (source, data->main_context);
|
|
g_source_unref (source);
|
|
nm_info ("Device %s activation scheduled...", nm_device_get_iface (dev));
|
|
}
|
|
|
|
|
|
static gboolean allowed_list_update_pending = FALSE;
|
|
|
|
/*
|
|
* nm_policy_allowed_ap_list_update
|
|
*
|
|
* Requery NetworkManagerInfo for a list of updated
|
|
* allowed wireless networks.
|
|
*
|
|
*/
|
|
static gboolean nm_policy_allowed_ap_list_update (gpointer user_data)
|
|
{
|
|
NMData *data = (NMData *)user_data;
|
|
|
|
allowed_list_update_pending = FALSE;
|
|
|
|
g_return_val_if_fail (data != NULL, FALSE);
|
|
|
|
nm_info ("Updating allowed wireless network lists.");
|
|
|
|
/* Query info daemon for network lists if its now running */
|
|
if (data->allowed_ap_list)
|
|
nm_ap_list_unref (data->allowed_ap_list);
|
|
if ((data->allowed_ap_list = nm_ap_list_new (NETWORK_TYPE_ALLOWED)))
|
|
nm_dbus_update_allowed_networks (data->dbus_connection, data->allowed_ap_list, data);
|
|
|
|
return (FALSE);
|
|
}
|
|
|
|
|
|
/*
|
|
* nm_policy_schedule_allowed_ap_list_update
|
|
*
|
|
* Schedule an update of the allowed AP list in the main thread.
|
|
*
|
|
*/
|
|
void nm_policy_schedule_allowed_ap_list_update (NMData *app_data)
|
|
{
|
|
static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
|
|
|
|
g_return_if_fail (app_data != NULL);
|
|
g_return_if_fail (app_data->main_context != NULL);
|
|
|
|
g_static_mutex_lock (&mutex);
|
|
|
|
if (allowed_list_update_pending == FALSE)
|
|
{
|
|
GSource *source = g_idle_source_new ();
|
|
/* We want this idle source to run before any other idle source */
|
|
g_source_set_priority (source, G_PRIORITY_HIGH_IDLE);
|
|
g_source_set_callback (source, nm_policy_allowed_ap_list_update, app_data, NULL);
|
|
g_source_attach (source, app_data->main_context);
|
|
g_source_unref (source);
|
|
|
|
allowed_list_update_pending = TRUE;
|
|
}
|
|
|
|
g_static_mutex_unlock (&mutex);
|
|
}
|
|
|
|
|
|
static gboolean device_list_update_pending = FALSE;
|
|
|
|
/*
|
|
* nm_policy_device_list_update_from_allowed_list
|
|
*
|
|
* Requery NetworkManagerInfo for a list of updated
|
|
* allowed wireless networks.
|
|
*
|
|
*/
|
|
static gboolean nm_policy_device_list_update_from_allowed_list (NMData *data)
|
|
{
|
|
GSList * elt;
|
|
|
|
device_list_update_pending = FALSE;
|
|
|
|
g_return_val_if_fail (data != NULL, FALSE);
|
|
|
|
for (elt = data->dev_list; elt != NULL; elt = g_slist_next (elt))
|
|
{
|
|
NMDevice *dev = (NMDevice *)(elt->data);
|
|
if (nm_device_is_802_11_wireless (dev))
|
|
{
|
|
if (nm_device_get_supports_wireless_scan (dev))
|
|
{
|
|
/* Once we have the list, copy in any relevant information from our Allowed list and fill
|
|
* in the ESSID of base stations that aren't broadcasting their ESSID, if we have their
|
|
* MAC address in our allowed list.
|
|
*/
|
|
nm_ap_list_copy_essids_by_address (nm_device_ap_list_get (dev), data->allowed_ap_list);
|
|
nm_ap_list_copy_properties (nm_device_ap_list_get (dev), data->allowed_ap_list);
|
|
}
|
|
else
|
|
nm_device_copy_allowed_to_dev_list (dev, data->allowed_ap_list);
|
|
|
|
nm_ap_list_remove_duplicate_essids (nm_device_ap_list_get (dev));
|
|
}
|
|
}
|
|
|
|
nm_policy_schedule_device_change_check (data);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
* nm_policy_schedule_device_ap_lists_update_from_allowed
|
|
*
|
|
* Schedule an update of each wireless device's AP list from
|
|
* the allowed list, in the main thread.
|
|
*
|
|
*/
|
|
void nm_policy_schedule_device_ap_lists_update_from_allowed (NMData *app_data)
|
|
{
|
|
static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
|
|
|
|
g_return_if_fail (app_data != NULL);
|
|
g_return_if_fail (app_data->main_context != NULL);
|
|
|
|
g_static_mutex_lock (&mutex);
|
|
|
|
if (device_list_update_pending == FALSE)
|
|
{
|
|
GSource *source = g_idle_source_new ();
|
|
|
|
/* We want this idle source to run before any other idle source */
|
|
g_source_set_priority (source, G_PRIORITY_HIGH_IDLE);
|
|
g_source_set_callback (source, (GSourceFunc) nm_policy_device_list_update_from_allowed_list, app_data, NULL);
|
|
g_source_attach (source, app_data->main_context);
|
|
g_source_unref (source);
|
|
|
|
device_list_update_pending = TRUE;
|
|
}
|
|
|
|
g_static_mutex_unlock (&mutex);
|
|
}
|