mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-03 17:30:16 +01:00
wifi: add callback to nm_supplicant_interface_request_scan()
While we request a scan, we are not yet actually scanning. That means, the supplicant's
"scanning" property will only change to TRUE a while after we initiate the scan. It may
even never happen.
We thus need to handle that the request is currently pending and react when the
request completes.
(cherry picked from commit 16c1869476)
This commit is contained in:
parent
6d0ea83949
commit
2eb398648f
3 changed files with 90 additions and 17 deletions
|
|
@ -1509,7 +1509,11 @@ request_wireless_scan (NMDeviceWifi *self,
|
|||
|
||||
nm_supplicant_interface_request_scan (priv->sup_iface,
|
||||
ssids ? (GBytes *const*) ssids->pdata : NULL,
|
||||
ssids ? ssids->len : 0u);
|
||||
ssids ? ssids->len : 0u,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
request_started = TRUE;
|
||||
} else
|
||||
_LOGD (LOGD_WIFI, "wifi-scan: scanning requested but not allowed at this time");
|
||||
|
|
|
|||
|
|
@ -2337,40 +2337,82 @@ nm_supplicant_interface_assoc (NMSupplicantInterface *self,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
NMSupplicantInterface *self;
|
||||
GCancellable *cancellable;
|
||||
NMSupplicantInterfaceRequestScanCallback callback;
|
||||
gpointer user_data;
|
||||
} ScanRequestData;
|
||||
|
||||
static void
|
||||
scan_request_cb (GObject *source, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
gs_unref_object NMSupplicantInterface *self_keep_alive = NULL;
|
||||
NMSupplicantInterface *self;
|
||||
gs_unref_variant GVariant *res = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
ScanRequestData *data = user_data;
|
||||
gboolean cancelled = FALSE;
|
||||
|
||||
res = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
|
||||
if (nm_utils_error_is_cancelled (error))
|
||||
return;
|
||||
|
||||
self = NM_SUPPLICANT_INTERFACE (user_data);
|
||||
if (error) {
|
||||
if (_nm_dbus_error_has_name (error, "fi.w1.wpa_supplicant1.Interface.ScanError"))
|
||||
_LOGD ("request-scan: could not get scan request result: %s", error->message);
|
||||
else {
|
||||
g_dbus_error_strip_remote_error (error);
|
||||
_LOGW ("request-scan: could not get scan request result: %s", error->message);
|
||||
if (nm_utils_error_is_cancelled (error)) {
|
||||
if (!data->callback) {
|
||||
/* the self instance was not kept alive. We also must not touch it. Return. */
|
||||
nm_g_object_unref (data->cancellable);
|
||||
nm_g_slice_free (data);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
_LOGT ("request-scan: request scanning success");
|
||||
cancelled = TRUE;
|
||||
}
|
||||
|
||||
self = data->self;
|
||||
if (data->callback) {
|
||||
/* the self instance was kept alive. Balance the reference count. */
|
||||
self_keep_alive = self;
|
||||
}
|
||||
|
||||
/* we don't propagate the error/success. That is, because either answer is not
|
||||
* reliable. What is important to us is whether the request completed, and
|
||||
* the current nm_supplicant_interface_get_scanning() state. */
|
||||
if (cancelled)
|
||||
_LOGD ("request-scan: request cancelled");
|
||||
else {
|
||||
if (error) {
|
||||
if (_nm_dbus_error_has_name (error, "fi.w1.wpa_supplicant1.Interface.ScanError"))
|
||||
_LOGD ("request-scan: could not get scan request result: %s", error->message);
|
||||
else {
|
||||
g_dbus_error_strip_remote_error (error);
|
||||
_LOGW ("request-scan: could not get scan request result: %s", error->message);
|
||||
}
|
||||
} else
|
||||
_LOGT ("request-scan: request scanning success");
|
||||
}
|
||||
|
||||
if (data->callback)
|
||||
data->callback (self, data->cancellable, data->user_data);
|
||||
|
||||
nm_g_object_unref (data->cancellable);
|
||||
nm_g_slice_free (data);
|
||||
}
|
||||
|
||||
void
|
||||
nm_supplicant_interface_request_scan (NMSupplicantInterface *self,
|
||||
GBytes *const*ssids,
|
||||
guint ssids_len)
|
||||
guint ssids_len,
|
||||
GCancellable *cancellable,
|
||||
NMSupplicantInterfaceRequestScanCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMSupplicantInterfacePrivate *priv;
|
||||
GVariantBuilder builder;
|
||||
ScanRequestData *data;
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (self));
|
||||
|
||||
nm_assert ( (!cancellable && !callback)
|
||||
|| (G_IS_CANCELLABLE (cancellable) && callback));
|
||||
|
||||
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
|
||||
_LOGT ("request-scan: request scanning (%u ssids)...", ssids_len);
|
||||
|
|
@ -2390,6 +2432,26 @@ nm_supplicant_interface_request_scan (NMSupplicantInterface *self,
|
|||
g_variant_builder_add (&builder, "{sv}", "SSIDs", g_variant_builder_end (&ssids_builder));
|
||||
}
|
||||
|
||||
data = g_slice_new (ScanRequestData);
|
||||
*data = (ScanRequestData) {
|
||||
.self = self,
|
||||
.callback = callback,
|
||||
.user_data = user_data,
|
||||
.cancellable = nm_g_object_ref (cancellable),
|
||||
};
|
||||
|
||||
if (callback) {
|
||||
/* A callback was provided. This keeps @self alive. The caller
|
||||
* must provide a cancellable as the caller must never leave an asynchronous
|
||||
* operation pending indefinitely. */
|
||||
nm_assert (G_IS_CANCELLABLE (cancellable));
|
||||
g_object_ref (self);
|
||||
} else {
|
||||
/* We don't keep @self alive, and we don't accept a cancellable either. */
|
||||
nm_assert (!cancellable);
|
||||
cancellable = priv->main_cancellable;
|
||||
}
|
||||
|
||||
_dbus_connection_call (self,
|
||||
NM_WPAS_DBUS_IFACE_INTERFACE,
|
||||
"Scan",
|
||||
|
|
@ -2397,9 +2459,9 @@ nm_supplicant_interface_request_scan (NMSupplicantInterface *self,
|
|||
G_VARIANT_TYPE ("()"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
DBUS_TIMEOUT_MSEC,
|
||||
priv->main_cancellable,
|
||||
cancellable,
|
||||
scan_request_cb,
|
||||
self);
|
||||
data);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -128,9 +128,16 @@ nm_supplicant_interface_disconnect_async (NMSupplicantInterface * self,
|
|||
NMSupplicantInterfaceDisconnectCb callback,
|
||||
gpointer user_data);
|
||||
|
||||
typedef void (*NMSupplicantInterfaceRequestScanCallback) (NMSupplicantInterface *self,
|
||||
GCancellable *cancellable,
|
||||
gpointer user_data);
|
||||
|
||||
void nm_supplicant_interface_request_scan (NMSupplicantInterface *self,
|
||||
GBytes *const*ssids,
|
||||
guint ssids_len);
|
||||
guint ssids_len,
|
||||
GCancellable *cancellable,
|
||||
NMSupplicantInterfaceRequestScanCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
NMSupplicantInterfaceState nm_supplicant_interface_get_state (NMSupplicantInterface * self);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue