mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-04-23 09:50:45 +02:00
wifi: merge branch 'th/supplicant-manager-fix-ref-count-rh1298007'
https://bugzilla.redhat.com/show_bug.cgi?id=1298007
https://bugzilla.redhat.com/show_bug.cgi?id=1241198
https://mail.gnome.org/archives/networkmanager-list/2016-February/msg00094.html
(cherry picked from commit de19bc20d0)
This commit is contained in:
commit
1fe054d319
6 changed files with 154 additions and 187 deletions
|
|
@ -424,35 +424,14 @@ device_get_setting (NMDevice *device, GType setting_type)
|
|||
/* 802.1X */
|
||||
|
||||
static void
|
||||
remove_supplicant_timeouts (NMDeviceEthernet *self)
|
||||
supplicant_interface_clear_handlers (NMDeviceEthernet *self)
|
||||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
|
||||
if (priv->supplicant.con_timeout_id) {
|
||||
g_source_remove (priv->supplicant.con_timeout_id);
|
||||
priv->supplicant.con_timeout_id = 0;
|
||||
}
|
||||
|
||||
if (priv->supplicant_timeout_id) {
|
||||
g_source_remove (priv->supplicant_timeout_id);
|
||||
priv->supplicant_timeout_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
remove_supplicant_interface_error_handler (NMDeviceEthernet *self)
|
||||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
|
||||
if (priv->supplicant.iface_error_id != 0) {
|
||||
g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_error_id);
|
||||
priv->supplicant.iface_error_id = 0;
|
||||
}
|
||||
|
||||
if (priv->supplicant.iface_con_error_cb_id > 0) {
|
||||
g_source_remove (priv->supplicant.iface_con_error_cb_id);
|
||||
priv->supplicant.iface_con_error_cb_id = 0;
|
||||
}
|
||||
nm_clear_g_source (&priv->supplicant_timeout_id);
|
||||
nm_clear_g_source (&priv->supplicant.con_timeout_id);
|
||||
nm_clear_g_source (&priv->supplicant.iface_con_error_cb_id);
|
||||
nm_clear_g_signal_handler (priv->supplicant.iface, &priv->supplicant.iface_error_id);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -460,18 +439,13 @@ supplicant_interface_release (NMDeviceEthernet *self)
|
|||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
|
||||
remove_supplicant_timeouts (self);
|
||||
remove_supplicant_interface_error_handler (self);
|
||||
supplicant_interface_clear_handlers (self);
|
||||
|
||||
if (priv->supplicant.iface_state_id > 0) {
|
||||
g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_state_id);
|
||||
priv->supplicant.iface_state_id = 0;
|
||||
}
|
||||
nm_clear_g_signal_handler (priv->supplicant.iface, &priv->supplicant.iface_state_id);
|
||||
|
||||
if (priv->supplicant.iface) {
|
||||
nm_supplicant_interface_disconnect (priv->supplicant.iface);
|
||||
nm_supplicant_manager_iface_release (priv->supplicant.mgr, priv->supplicant.iface);
|
||||
priv->supplicant.iface = NULL;
|
||||
g_clear_object (&priv->supplicant.iface);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -626,8 +600,7 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
|||
}
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_COMPLETED:
|
||||
remove_supplicant_interface_error_handler (self);
|
||||
remove_supplicant_timeouts (self);
|
||||
supplicant_interface_clear_handlers (self);
|
||||
|
||||
/* If this is the initial association during device activation,
|
||||
* schedule the next activation stage.
|
||||
|
|
@ -647,7 +620,6 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
|||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
|
||||
supplicant_interface_release (self);
|
||||
remove_supplicant_timeouts (self);
|
||||
|
||||
if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) {
|
||||
nm_device_state_changed (device,
|
||||
|
|
@ -774,14 +746,15 @@ supplicant_interface_init (NMDeviceEthernet *self)
|
|||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
|
||||
/* Create supplicant interface */
|
||||
priv->supplicant.iface = nm_supplicant_manager_iface_get (priv->supplicant.mgr,
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
FALSE);
|
||||
supplicant_interface_release (self);
|
||||
|
||||
priv->supplicant.iface = nm_supplicant_manager_create_interface (priv->supplicant.mgr,
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
FALSE);
|
||||
|
||||
if (!priv->supplicant.iface) {
|
||||
_LOGE (LOGD_DEVICE | LOGD_ETHER,
|
||||
"Couldn't initialize supplicant interface");
|
||||
supplicant_interface_release (self);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -1644,10 +1617,9 @@ dispose (GObject *object)
|
|||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (object);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
|
||||
if (priv->pppoe_wait_id) {
|
||||
g_source_remove (priv->pppoe_wait_id);
|
||||
priv->pppoe_wait_id = 0;
|
||||
}
|
||||
supplicant_interface_release (self);
|
||||
|
||||
nm_clear_g_source (&priv->pppoe_wait_id);
|
||||
|
||||
dcb_timeout_cleanup (NM_DEVICE (self));
|
||||
dcb_carrier_cleanup (NM_DEVICE (self));
|
||||
|
|
|
|||
|
|
@ -146,8 +146,6 @@ static gboolean check_scanning_allowed (NMDeviceWifi *self);
|
|||
|
||||
static void schedule_scan (NMDeviceWifi *self, gboolean backoff);
|
||||
|
||||
static void cancel_pending_scan (NMDeviceWifi *self);
|
||||
|
||||
static void cleanup_association_attempt (NMDeviceWifi * self,
|
||||
gboolean disconnect);
|
||||
|
||||
|
|
@ -210,13 +208,12 @@ supplicant_interface_acquire (NMDeviceWifi *self)
|
|||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
/* interface already acquired? */
|
||||
g_return_val_if_fail (priv->sup_iface == NULL, TRUE);
|
||||
g_return_val_if_fail (!priv->sup_iface, TRUE);
|
||||
|
||||
priv->sup_iface = nm_supplicant_manager_iface_get (priv->sup_mgr,
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
TRUE);
|
||||
if (priv->sup_iface == NULL) {
|
||||
priv->sup_iface = nm_supplicant_manager_create_interface (priv->sup_mgr,
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
TRUE);
|
||||
if (!priv->sup_iface) {
|
||||
_LOGE (LOGD_WIFI, "Couldn't initialize supplicant interface");
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -261,7 +258,7 @@ supplicant_interface_release (NMDeviceWifi *self)
|
|||
|
||||
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
|
||||
cancel_pending_scan (self);
|
||||
nm_clear_g_source (&priv->pending_scan_id);
|
||||
|
||||
/* Reset the scan interval to be pretty frequent when disconnected */
|
||||
priv->scan_interval = SCAN_INTERVAL_MIN + SCAN_INTERVAL_STEP;
|
||||
|
|
@ -274,16 +271,13 @@ supplicant_interface_release (NMDeviceWifi *self)
|
|||
}
|
||||
|
||||
if (priv->sup_iface) {
|
||||
remove_supplicant_interface_error_handler (self);
|
||||
|
||||
/* Clear supplicant interface signal handlers */
|
||||
g_signal_handlers_disconnect_by_data (priv->sup_iface, self);
|
||||
|
||||
/* Tell the supplicant to disconnect from the current AP */
|
||||
nm_supplicant_interface_disconnect (priv->sup_iface);
|
||||
|
||||
nm_supplicant_manager_iface_release (priv->sup_mgr, priv->sup_iface);
|
||||
priv->sup_iface = NULL;
|
||||
g_clear_object (&priv->sup_iface);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -734,7 +728,7 @@ deactivate (NMDevice *device)
|
|||
|
||||
/* Ensure we trigger a scan after deactivating a Hotspot */
|
||||
if (old_mode == NM_802_11_MODE_AP) {
|
||||
cancel_pending_scan (self);
|
||||
nm_clear_g_source (&priv->pending_scan_id);
|
||||
request_wireless_scan (self, NULL);
|
||||
}
|
||||
}
|
||||
|
|
@ -1237,6 +1231,7 @@ request_scan_cb (NMDevice *device,
|
|||
gpointer user_data)
|
||||
{
|
||||
NMDeviceWifi *self = NM_DEVICE_WIFI (device);
|
||||
NMDeviceWifiPrivate *priv;
|
||||
GError *local = NULL;
|
||||
gs_unref_hashtable GHashTable *new_scan_options = user_data;
|
||||
|
||||
|
|
@ -1254,7 +1249,9 @@ request_scan_cb (NMDevice *device,
|
|||
return;
|
||||
}
|
||||
|
||||
cancel_pending_scan (self);
|
||||
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
|
||||
nm_clear_g_source (&priv->pending_scan_id);
|
||||
request_wireless_scan (self, new_scan_options);
|
||||
dbus_g_method_return (context);
|
||||
}
|
||||
|
|
@ -1554,7 +1551,7 @@ schedule_scan (NMDeviceWifi *self, gboolean backoff)
|
|||
/* Cancel the pending scan if it would happen later than (now + the scan_interval) */
|
||||
if (priv->pending_scan_id) {
|
||||
if (now + priv->scan_interval < priv->scheduled_scan_time)
|
||||
cancel_pending_scan (self);
|
||||
nm_clear_g_source (&priv->pending_scan_id);
|
||||
}
|
||||
|
||||
if (!priv->pending_scan_id) {
|
||||
|
|
@ -1587,18 +1584,6 @@ schedule_scan (NMDeviceWifi *self, gboolean backoff)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cancel_pending_scan (NMDeviceWifi *self)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
|
||||
if (priv->pending_scan_id) {
|
||||
g_source_remove (priv->pending_scan_id);
|
||||
priv->pending_scan_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_scan_done_cb (NMSupplicantInterface *iface,
|
||||
gboolean success,
|
||||
|
|
@ -2485,7 +2470,7 @@ build_supplicant_config (NMDeviceWifi *self,
|
|||
NMSettingWireless *s_wireless;
|
||||
NMSettingWirelessSecurity *s_wireless_sec;
|
||||
|
||||
g_return_val_if_fail (self != NULL, NULL);
|
||||
g_return_val_if_fail (priv->sup_iface, NULL);
|
||||
|
||||
s_wireless = nm_connection_get_setting_wireless (connection);
|
||||
g_return_val_if_fail (s_wireless != NULL, NULL);
|
||||
|
|
@ -3115,7 +3100,7 @@ device_state_changed (NMDevice *device,
|
|||
case NM_DEVICE_STATE_DISCONNECTED:
|
||||
/* Kick off a scan to get latest results */
|
||||
priv->scan_interval = SCAN_INTERVAL_MIN;
|
||||
cancel_pending_scan (self);
|
||||
nm_clear_g_source (&priv->pending_scan_id);
|
||||
request_wireless_scan (self, NULL);
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -368,7 +368,7 @@ parse_capabilities (NMSupplicantInterface *self, GVariant *capabilities)
|
|||
*/
|
||||
priv->max_scan_ssids = CLAMP (max_scan_ssids, 0, 5);
|
||||
nm_log_info (LOGD_SUPPLICANT, "(%s) supports %d scan SSIDs",
|
||||
priv->dev, priv->max_scan_ssids);
|
||||
priv->dev, priv->max_scan_ssids);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -822,7 +822,7 @@ on_wpas_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_d
|
|||
}
|
||||
|
||||
static void
|
||||
interface_add (NMSupplicantInterface *self, gboolean is_wireless)
|
||||
interface_add (NMSupplicantInterface *self)
|
||||
{
|
||||
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
|
||||
|
|
@ -831,8 +831,6 @@ interface_add (NMSupplicantInterface *self, gboolean is_wireless)
|
|||
|
||||
nm_log_dbg (LOGD_SUPPLICANT, "(%s): adding interface to supplicant", priv->dev);
|
||||
|
||||
priv->is_wireless = is_wireless;
|
||||
|
||||
/* Move to starting to prevent double-calls of interface_add() */
|
||||
set_state (self, NM_SUPPLICANT_INTERFACE_STATE_STARTING);
|
||||
|
||||
|
|
@ -856,14 +854,18 @@ void
|
|||
nm_supplicant_interface_set_supplicant_available (NMSupplicantInterface *self,
|
||||
gboolean available)
|
||||
{
|
||||
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
NMSupplicantInterfacePrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (self));
|
||||
|
||||
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
|
||||
if (available) {
|
||||
/* This can happen if the supplicant couldn't be activated but
|
||||
* for some reason was started after the activation failure.
|
||||
*/
|
||||
if (priv->state == NM_SUPPLICANT_INTERFACE_STATE_INIT)
|
||||
interface_add (self, priv->is_wireless);
|
||||
interface_add (self);
|
||||
} else {
|
||||
/* The supplicant stopped; so we must tear down the interface */
|
||||
set_state (self, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
|
||||
|
|
@ -1220,14 +1222,6 @@ nm_supplicant_interface_state_to_string (guint32 state)
|
|||
return "unknown";
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_supplicant_interface_get_device (NMSupplicantInterface * self)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NULL);
|
||||
|
||||
return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->dev;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_supplicant_interface_get_object_path (NMSupplicantInterface *self)
|
||||
{
|
||||
|
|
@ -1258,8 +1252,7 @@ NMSupplicantInterface *
|
|||
nm_supplicant_interface_new (const char *ifname,
|
||||
gboolean is_wireless,
|
||||
gboolean fast_supported,
|
||||
ApSupport ap_support,
|
||||
gboolean start_now)
|
||||
ApSupport ap_support)
|
||||
{
|
||||
NMSupplicantInterface *self;
|
||||
NMSupplicantInterfacePrivate *priv;
|
||||
|
|
@ -1270,13 +1263,10 @@ nm_supplicant_interface_new (const char *ifname,
|
|||
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
|
||||
priv->dev = g_strdup (ifname);
|
||||
priv->is_wireless = is_wireless;
|
||||
priv->is_wireless = !!is_wireless;
|
||||
priv->fast_supported = fast_supported;
|
||||
priv->ap_support = ap_support;
|
||||
|
||||
if (start_now)
|
||||
interface_add (self, priv->is_wireless);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,8 +122,7 @@ GType nm_supplicant_interface_get_type (void);
|
|||
NMSupplicantInterface * nm_supplicant_interface_new (const char *ifname,
|
||||
gboolean is_wireless,
|
||||
gboolean fast_supported,
|
||||
ApSupport ap_support,
|
||||
gboolean start_now);
|
||||
ApSupport ap_support);
|
||||
|
||||
void nm_supplicant_interface_set_supplicant_available (NMSupplicantInterface *self,
|
||||
gboolean available);
|
||||
|
|
@ -133,8 +132,6 @@ gboolean nm_supplicant_interface_set_config (NMSupplicantInterface * iface,
|
|||
|
||||
void nm_supplicant_interface_disconnect (NMSupplicantInterface * iface);
|
||||
|
||||
const char * nm_supplicant_interface_get_device (NMSupplicantInterface * iface);
|
||||
|
||||
const char *nm_supplicant_interface_get_object_path (NMSupplicantInterface * iface);
|
||||
|
||||
gboolean nm_supplicant_interface_request_scan (NMSupplicantInterface * self, const GPtrArray *ssids);
|
||||
|
|
|
|||
|
|
@ -43,11 +43,11 @@ typedef struct {
|
|||
GCancellable * cancellable;
|
||||
gboolean running;
|
||||
|
||||
GHashTable * ifaces;
|
||||
gboolean fast_supported;
|
||||
ApSupport ap_support;
|
||||
guint die_count_reset_id;
|
||||
guint die_count;
|
||||
GSList *ifaces;
|
||||
gboolean fast_supported;
|
||||
ApSupport ap_support;
|
||||
guint die_count_reset_id;
|
||||
guint die_count;
|
||||
} NMSupplicantManagerPrivate;
|
||||
|
||||
/********************************************************************/
|
||||
|
|
@ -58,70 +58,40 @@ die_count_exceeded (guint32 count)
|
|||
return count > 2;
|
||||
}
|
||||
|
||||
NMSupplicantInterface *
|
||||
nm_supplicant_manager_iface_get (NMSupplicantManager * self,
|
||||
const char *ifname,
|
||||
gboolean is_wireless)
|
||||
static gboolean
|
||||
is_available (NMSupplicantManager *self)
|
||||
{
|
||||
NMSupplicantManagerPrivate *priv;
|
||||
NMSupplicantInterface *iface = NULL;
|
||||
gboolean start_now;
|
||||
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), NULL);
|
||||
g_return_val_if_fail (ifname != NULL, NULL);
|
||||
|
||||
priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
iface = g_hash_table_lookup (priv->ifaces, ifname);
|
||||
if (!iface) {
|
||||
/* If we're making the supplicant take a time out for a bit, don't
|
||||
* let the supplicant interface start immediately, just let it hang
|
||||
* around in INIT state until we're ready to talk to the supplicant
|
||||
* again.
|
||||
*/
|
||||
start_now = !die_count_exceeded (priv->die_count);
|
||||
|
||||
nm_log_dbg (LOGD_SUPPLICANT, "(%s): creating new supplicant interface", ifname);
|
||||
iface = nm_supplicant_interface_new (ifname,
|
||||
is_wireless,
|
||||
priv->fast_supported,
|
||||
priv->ap_support,
|
||||
start_now);
|
||||
if (iface) {
|
||||
g_hash_table_insert (priv->ifaces,
|
||||
(char *) nm_supplicant_interface_get_ifname (iface),
|
||||
iface);
|
||||
}
|
||||
} else {
|
||||
/* nm_supplicant_manager_iface_get() and release() implements no form of ref-counting
|
||||
* to properly handle reusing a cached instance. It's also unclear whether that is
|
||||
* even necessary or desired. Assert here and error out (rh #1298007). */
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
return iface;
|
||||
return priv->running
|
||||
&& !die_count_exceeded (priv->die_count);
|
||||
}
|
||||
|
||||
void
|
||||
nm_supplicant_manager_iface_release (NMSupplicantManager *self,
|
||||
NMSupplicantInterface *iface)
|
||||
/********************************************************************/
|
||||
|
||||
static void
|
||||
_sup_iface_last_ref (gpointer data,
|
||||
GObject *object,
|
||||
gboolean is_last_ref)
|
||||
{
|
||||
NMSupplicantManager *self = data;
|
||||
NMSupplicantManagerPrivate *priv;
|
||||
const char *ifname, *op;
|
||||
NMSupplicantInterface *sup_iface = (NMSupplicantInterface *) object;
|
||||
const char *op;
|
||||
|
||||
g_return_if_fail (NM_IS_SUPPLICANT_MANAGER (self));
|
||||
g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (iface));
|
||||
|
||||
ifname = nm_supplicant_interface_get_ifname (iface);
|
||||
g_assert (ifname);
|
||||
g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (sup_iface));
|
||||
g_return_if_fail (is_last_ref);
|
||||
|
||||
priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (g_hash_table_lookup (priv->ifaces, ifname) == iface);
|
||||
if (!g_slist_find (priv->ifaces, sup_iface))
|
||||
g_return_if_reached ();
|
||||
|
||||
/* Ask wpa_supplicant to remove this interface */
|
||||
op = nm_supplicant_interface_get_object_path (iface);
|
||||
if (priv->running && priv->proxy && op) {
|
||||
if ( priv->running
|
||||
&& priv->proxy
|
||||
&& (op = nm_supplicant_interface_get_object_path (sup_iface))) {
|
||||
g_dbus_proxy_call (priv->proxy,
|
||||
"RemoveInterface",
|
||||
g_variant_new ("(o)", op),
|
||||
|
|
@ -132,15 +102,69 @@ nm_supplicant_manager_iface_release (NMSupplicantManager *self,
|
|||
NULL);
|
||||
}
|
||||
|
||||
g_hash_table_remove (priv->ifaces, ifname);
|
||||
priv->ifaces = g_slist_remove (priv->ifaces, sup_iface);
|
||||
g_object_remove_toggle_ref ((GObject *) sup_iface, _sup_iface_last_ref, self);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_supplicant_manager_create_interface:
|
||||
* @self: the #NMSupplicantManager
|
||||
* @ifname: the interface for which to obtain the supplicant interface
|
||||
* @is_wireless: whether the interface is supposed to be wireless.
|
||||
*
|
||||
* Note: the manager owns a reference to the instance and the only way to
|
||||
* get the manager to release it, is by dropping all other references
|
||||
* to the supplicant-interface (or destroying the manager).
|
||||
*
|
||||
* Retruns: (transfer-full): returns a #NMSupplicantInterface or %NULL.
|
||||
* Must be unrefed at the end.
|
||||
* */
|
||||
NMSupplicantInterface *
|
||||
nm_supplicant_manager_create_interface (NMSupplicantManager *self,
|
||||
const char *ifname,
|
||||
gboolean is_wireless)
|
||||
{
|
||||
NMSupplicantManagerPrivate *priv;
|
||||
NMSupplicantInterface *iface;
|
||||
GSList *ifaces;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), NULL);
|
||||
g_return_val_if_fail (ifname != NULL, NULL);
|
||||
|
||||
priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
nm_log_dbg (LOGD_SUPPLICANT, "(%s): creating new supplicant interface", ifname);
|
||||
|
||||
/* assert against not requesting duplicate interfaces. */
|
||||
for (ifaces = priv->ifaces; ifaces; ifaces = ifaces->next) {
|
||||
if (g_strcmp0 (nm_supplicant_interface_get_ifname (ifaces->data), ifname) == 0)
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
iface = nm_supplicant_interface_new (ifname,
|
||||
is_wireless,
|
||||
priv->fast_supported,
|
||||
priv->ap_support);
|
||||
|
||||
priv->ifaces = g_slist_prepend (priv->ifaces, iface);
|
||||
g_object_add_toggle_ref ((GObject *) iface, _sup_iface_last_ref, self);
|
||||
|
||||
/* If we're making the supplicant take a time out for a bit, don't
|
||||
* let the supplicant interface start immediately, just let it hang
|
||||
* around in INIT state until we're ready to talk to the supplicant
|
||||
* again.
|
||||
*/
|
||||
if (is_available (self))
|
||||
nm_supplicant_interface_set_supplicant_available (iface, TRUE);
|
||||
|
||||
return iface;
|
||||
}
|
||||
|
||||
static void
|
||||
update_capabilities (NMSupplicantManager *self)
|
||||
{
|
||||
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
|
||||
NMSupplicantInterface *iface;
|
||||
GHashTableIter hash_iter;
|
||||
GSList *ifaces;
|
||||
const char **array;
|
||||
GVariant *value;
|
||||
|
||||
|
|
@ -168,9 +192,8 @@ update_capabilities (NMSupplicantManager *self)
|
|||
}
|
||||
|
||||
/* Tell all interfaces about results of the AP check */
|
||||
g_hash_table_iter_init (&hash_iter, priv->ifaces);
|
||||
while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &iface))
|
||||
nm_supplicant_interface_set_ap_support (iface, priv->ap_support);
|
||||
for (ifaces = priv->ifaces; ifaces; ifaces = ifaces->next)
|
||||
nm_supplicant_interface_set_ap_support (ifaces->data, priv->ap_support);
|
||||
|
||||
nm_log_dbg (LOGD_SUPPLICANT, "AP mode is %ssupported",
|
||||
(priv->ap_support == AP_SUPPORT_YES) ? "" :
|
||||
|
|
@ -196,23 +219,20 @@ static void
|
|||
availability_changed (NMSupplicantManager *self, gboolean available)
|
||||
{
|
||||
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
|
||||
GList *ifaces, *iter;
|
||||
GSList *ifaces, *iter;
|
||||
|
||||
/* priv->ifaces may be modified if availability changes; can't use GHashTableIter */
|
||||
ifaces = g_hash_table_get_values (priv->ifaces);
|
||||
if (!priv->ifaces)
|
||||
return;
|
||||
|
||||
/* setting the supplicant as unavailable might cause the caller to unref
|
||||
* the supplicant (and thus remove the instance from the list of interfaces.
|
||||
* Delay that by taking an additional reference first. */
|
||||
ifaces = g_slist_copy (priv->ifaces);
|
||||
for (iter = ifaces; iter; iter = iter->next)
|
||||
nm_supplicant_interface_set_supplicant_available (NM_SUPPLICANT_INTERFACE (iter->data), available);
|
||||
g_list_free (ifaces);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_available (NMSupplicantManager *self)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), FALSE);
|
||||
|
||||
if (die_count_exceeded (NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->die_count))
|
||||
return FALSE;
|
||||
return NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->running;
|
||||
g_object_ref (iter->data);
|
||||
for (iter = ifaces; iter; iter = iter->next)
|
||||
nm_supplicant_interface_set_supplicant_available (iter->data, available);
|
||||
g_slist_free_full (ifaces, g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -328,8 +348,6 @@ nm_supplicant_manager_init (NMSupplicantManager *self)
|
|||
{
|
||||
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
priv->ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
|
||||
|
||||
priv->cancellable = g_cancellable_new ();
|
||||
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
|
|
@ -345,7 +363,9 @@ nm_supplicant_manager_init (NMSupplicantManager *self)
|
|||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (object);
|
||||
NMSupplicantManager *self = (NMSupplicantManager *) object;
|
||||
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
|
||||
GSList *ifaces;
|
||||
|
||||
if (priv->die_count_reset_id) {
|
||||
g_source_remove (priv->die_count_reset_id);
|
||||
|
|
@ -357,7 +377,13 @@ dispose (GObject *object)
|
|||
g_clear_object (&priv->cancellable);
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->ifaces, g_hash_table_unref);
|
||||
if (priv->ifaces) {
|
||||
for (ifaces = priv->ifaces; ifaces; ifaces = ifaces->next)
|
||||
g_object_remove_toggle_ref (ifaces->data, _sup_iface_last_ref, self);
|
||||
g_slist_free (priv->ifaces);
|
||||
priv->ifaces = NULL;
|
||||
}
|
||||
|
||||
g_clear_object (&priv->proxy);
|
||||
|
||||
G_OBJECT_CLASS (nm_supplicant_manager_parent_class)->dispose (object);
|
||||
|
|
|
|||
|
|
@ -49,11 +49,8 @@ GType nm_supplicant_manager_get_type (void);
|
|||
|
||||
NMSupplicantManager *nm_supplicant_manager_get (void);
|
||||
|
||||
NMSupplicantInterface *nm_supplicant_manager_iface_get (NMSupplicantManager *mgr,
|
||||
const char *ifname,
|
||||
gboolean is_wireless);
|
||||
|
||||
void nm_supplicant_manager_iface_release (NMSupplicantManager *mgr,
|
||||
NMSupplicantInterface *iface);
|
||||
NMSupplicantInterface *nm_supplicant_manager_create_interface (NMSupplicantManager *mgr,
|
||||
const char *ifname,
|
||||
gboolean is_wireless);
|
||||
|
||||
#endif /* __NETWORKMANAGER_SUPPLICANT_MANAGER_H__ */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue