wifi-p2p: rework setting pending action waiting for supplicant

Previously, we might have a pending action 'waiting-for-supplicant'
registered, although the device was not waiting:

    <info>  [1549611177.5815] device (wlan0): supplicant interface state: starting -> ready
    <debug> [1549611177.5816] device[0x55d1781ae5d0] (p2p-dev-wlan0): P2P: Releasing WPA supplicant interfaces.
    <debug> [1549611177.5816] device[0x55d1781ae5d0] (p2p-dev-wlan0): P2P: WPA supplicant management interface changed to /fi/w1/wpa_supplicant1/Interfaces/1.
    <trace> [1549611177.5816] device[0x55d1781ae5d0] (p2p-dev-wlan0): remove_pending_action (0): 'waiting-for-supplicant' not pending (expected)
    <debug> [1549611177.5816] device[0x55d1781ae5d0] (p2p-dev-wlan0): constructed (NMDeviceWifiP2P)
    <debug> [1549611177.5816] device[0x55d1781ae5d0] (p2p-dev-wlan0): add_pending_action (1): 'waiting-for-supplicant'

The previous commit already fixed this bug by dropping the constructor
property for NM_DEVICE_WIFI_P2P_MGMT_IFACE.

Still, refactor handling of pending actions to keep track of whether we
have a pending action registered.
This commit is contained in:
Thomas Haller 2019-02-08 09:03:00 +01:00
parent 75741ef5c8
commit 3c989f30d6

View file

@ -72,7 +72,9 @@ typedef struct {
guint peer_dump_id;
guint peer_missing_id;
gboolean group_owner;
bool group_owner:1;
bool is_waiting_for_supplicant:1;
} NMDeviceWifiP2PPrivate;
struct _NMDeviceWifiP2P {
@ -95,7 +97,7 @@ static const GDBusSignalInfo nm_signal_info_wifi_p2p_peer_added;
static const GDBusSignalInfo nm_signal_info_wifi_p2p_peer_removed;
static void supplicant_group_interface_release (NMDeviceWifiP2P *self);
static void supplicant_interfaces_release (NMDeviceWifiP2P *self);
static void supplicant_interfaces_release (NMDeviceWifiP2P *self, gboolean set_is_waiting);
/*****************************************************************************/
@ -144,6 +146,24 @@ schedule_peer_list_dump (NMDeviceWifiP2P *self)
/*****************************************************************************/
static void
_set_is_waiting_for_supplicant (NMDeviceWifiP2P *self, gboolean is_waiting)
{
NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
if (priv->is_waiting_for_supplicant == (!!is_waiting))
return;
priv->is_waiting_for_supplicant = is_waiting;
if (is_waiting)
nm_device_add_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE);
else
nm_device_remove_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE);
}
/*****************************************************************************/
static gboolean
check_connection_peer_joined (NMDeviceWifiP2P *device)
{
@ -687,14 +707,14 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
if (old_state < NM_SUPPLICANT_INTERFACE_STATE_READY)
nm_device_remove_pending_action (device, NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE);
_set_is_waiting_for_supplicant (self, FALSE);
break;
case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
nm_device_queue_recheck_available (device,
NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
supplicant_interfaces_release (self);
supplicant_interfaces_release (self, TRUE);
break;
default:
break;
@ -810,7 +830,7 @@ supplicant_group_iface_state_cb (NMSupplicantInterface *iface,
}
if (old_state < NM_SUPPLICANT_INTERFACE_STATE_READY)
nm_device_remove_pending_action (device, NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE);
_set_is_waiting_for_supplicant (self, FALSE);
check_group_iface_ready (self);
break;
@ -885,7 +905,7 @@ supplicant_iface_group_started_cb (NMSupplicantInterface *iface,
self);
if (nm_supplicant_interface_get_state (priv->group_iface) < NM_SUPPLICANT_INTERFACE_STATE_READY)
nm_device_add_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, FALSE);
_set_is_waiting_for_supplicant (self, TRUE);
check_group_iface_ready (self);
}
@ -893,47 +913,39 @@ supplicant_iface_group_started_cb (NMSupplicantInterface *iface,
static void
supplicant_group_interface_release (NMDeviceWifiP2P *self)
{
NMDeviceWifiP2PPrivate *priv;
NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
g_return_if_fail (self != NULL);
if (!priv->group_iface)
return;
priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
g_signal_handlers_disconnect_by_data (priv->group_iface, self);
if (priv->group_iface) {
/* Tell the supplicant to disconnect from the current Group/Peer */
nm_supplicant_interface_p2p_disconnect (priv->group_iface);
nm_supplicant_interface_p2p_disconnect (priv->group_iface);
/* Clear supplicant interface signal handlers */
g_signal_handlers_disconnect_by_data (priv->group_iface, self);
g_clear_object (&priv->group_iface);
}
g_clear_object (&priv->group_iface);
}
static void
supplicant_interfaces_release (NMDeviceWifiP2P *self)
supplicant_interfaces_release (NMDeviceWifiP2P *self, gboolean set_is_waiting)
{
NMDeviceWifiP2PPrivate *priv;
g_return_if_fail (self != NULL);
priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
_LOGD (LOGD_DEVICE | LOGD_WIFI, "P2P: Releasing WPA supplicant interfaces.");
NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
nm_clear_g_source (&priv->peer_dump_id);
remove_all_peers (self);
if (priv->mgmt_iface) {
/* Clear supplicant interface signal handlers */
_LOGD (LOGD_DEVICE | LOGD_WIFI, "P2P: Releasing WPA supplicant interface.");
g_signal_handlers_disconnect_by_data (priv->mgmt_iface, self);
g_clear_object (&priv->mgmt_iface);
nm_device_add_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, FALSE);
}
supplicant_group_interface_release (self);
if (set_is_waiting)
_set_is_waiting_for_supplicant (self, TRUE);
}
static void
@ -954,7 +966,7 @@ device_state_changed (NMDevice *device,
* will happen during initialization.
*/
if (priv->mgmt_iface && old_state > new_state)
supplicant_interfaces_release (self);
supplicant_interfaces_release (self, TRUE);
/* TODO: More cleanup needed? */
} else
@ -966,7 +978,7 @@ device_state_changed (NMDevice *device,
case NM_DEVICE_STATE_UNAVAILABLE:
if ( !priv->mgmt_iface
|| nm_supplicant_interface_get_state (priv->mgmt_iface) < NM_SUPPLICANT_INTERFACE_STATE_READY)
nm_device_add_pending_action (device, NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, FALSE);
_set_is_waiting_for_supplicant (self, TRUE);
break;
case NM_DEVICE_STATE_NEED_AUTH:
@ -1079,36 +1091,34 @@ impl_device_wifi_p2p_stop_find (NMDBusObject *obj,
NMSupplicantInterface *
nm_device_wifi_p2p_get_mgmt_iface (NMDeviceWifiP2P *self)
{
NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
g_return_val_if_fail (NM_IS_DEVICE_WIFI_P2P (self), NULL);
return priv->mgmt_iface;
return NM_DEVICE_WIFI_P2P_GET_PRIVATE (self)->mgmt_iface;
}
void
nm_device_wifi_p2p_set_mgmt_iface (NMDeviceWifiP2P *self,
NMSupplicantInterface *iface)
{
NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
NMDeviceWifiP2PPrivate *priv;
g_return_if_fail (NM_IS_DEVICE_WIFI_P2P (self));
g_return_if_fail (!iface || NM_IS_SUPPLICANT_INTERFACE (iface));
priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
/* Don't do anything if nothing changed. */
if (priv->mgmt_iface == iface)
return;
goto done;
supplicant_interfaces_release (self);
supplicant_interfaces_release (self, FALSE);
if (iface == NULL) {
_LOGD (LOGD_DEVICE | LOGD_WIFI, "P2P: WPA supplicant management interface cleared.");
return;
}
if (!iface)
goto done;
_LOGD (LOGD_DEVICE | LOGD_WIFI, "P2P: WPA supplicant management interface changed to %s.", nm_supplicant_interface_get_object_path (iface));
priv->mgmt_iface = g_object_ref (iface);
/* We are not waiting on the supplicant anymore if the state is ready. */
if (nm_supplicant_interface_get_state (priv->mgmt_iface) >= NM_SUPPLICANT_INTERFACE_STATE_READY)
nm_device_remove_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, FALSE);
g_signal_connect (priv->mgmt_iface, NM_SUPPLICANT_INTERFACE_STATE,
G_CALLBACK (supplicant_iface_state_cb),
self);
@ -1121,6 +1131,12 @@ nm_device_wifi_p2p_set_mgmt_iface (NMDeviceWifiP2P *self,
g_signal_connect (priv->mgmt_iface, NM_SUPPLICANT_INTERFACE_GROUP_STARTED,
G_CALLBACK (supplicant_iface_group_started_cb),
self);
done:
_set_is_waiting_for_supplicant (self,
!priv->mgmt_iface
|| ( nm_supplicant_interface_get_state (priv->mgmt_iface)
< NM_SUPPLICANT_INTERFACE_STATE_READY));
}
void
@ -1222,11 +1238,10 @@ static void
constructed (GObject *object)
{
NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (object);
NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
G_OBJECT_CLASS (nm_device_wifi_p2p_parent_class)->constructed (object);
nm_device_add_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, FALSE);
_set_is_waiting_for_supplicant (self, TRUE);
}
NMDeviceWifiP2P *
@ -1249,7 +1264,7 @@ dispose (GObject *object)
g_clear_object (&priv->sup_mgr);
supplicant_interfaces_release (self);
supplicant_interfaces_release (self, FALSE);
G_OBJECT_CLASS (nm_device_wifi_p2p_parent_class)->dispose (object);
}
@ -1302,8 +1317,6 @@ nm_device_wifi_p2p_class_init (NMDeviceWifiP2PClass *klass)
device_class->state_changed = device_state_changed;
/*klass->scanning_prohibited = scanning_prohibited;*/
obj_properties[PROP_GROUP_OWNER] =
g_param_spec_boolean (NM_DEVICE_WIFI_P2P_GROUP_OWNER, "", "",
FALSE,