summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-03-18 10:34:07 +0100
committerThomas Haller <thaller@redhat.com>2020-03-18 11:54:23 +0100
commit41646cf0da119212eab79828baf1ea5004e24815 (patch)
tree7450ab84ca4609fd21d876aec19dea125828b493
parent9575c2ce9ede0588bac10eed53d3bfb1af1a3277 (diff)
downloadNetworkManager-th/cli-device-wifi-list-rework.tar.gz
cli: rework do_device_wifi_list() to scan and print Wi-Fi listth/cli-device-wifi-list-rework
Drop the special casing of not scanning. Now do_device_wifi_list() always handles the scan list in a callback. Also fix the error code for scanning for a certain "bssid", which previously was not set if scanning was not performed: $ nmcli device wifi list --rescan no bssid bogus Success
-rw-r--r--clients/cli/devices.c216
1 files changed, 112 insertions, 104 deletions
diff --git a/clients/cli/devices.c b/clients/cli/devices.c
index 79183ff26c..9c394df72d 100644
--- a/clients/cli/devices.c
+++ b/clients/cli/devices.c
@@ -11,14 +11,13 @@
#include <stdlib.h>
#include <readline/readline.h>
-#include "nm-secret-agent-simple.h"
+#include "nm-glib-aux/nm-secret-utils.h"
+#include "common.h"
+#include "connections.h"
#include "nm-client-utils.h"
-
+#include "nm-secret-agent-simple.h"
#include "polkit-agent.h"
#include "utils.h"
-#include "common.h"
-#include "connections.h"
-#include "nm-glib-aux/nm-secret-utils.h"
/* define some prompts */
#define PROMPT_INTERFACE _("Interface: ")
@@ -2822,7 +2821,8 @@ wifi_print_aps (NMDeviceWifi *wifi,
NmCli *nmc,
GArray *_out_indices,
const NMMetaAbstractInfo *const*tmpl,
- const char *bssid_user)
+ const char *bssid_user,
+ gboolean *bssid_found)
{
NMAccessPoint *ap = NULL;
const GPtrArray *aps;
@@ -2873,7 +2873,7 @@ wifi_print_aps (NMDeviceWifi *wifi,
print_data (&nmc->nmc_config, out_indices, header_name, 0, &out);
g_free (info);
- nmc->return_value = NMC_RESULT_SUCCESS;
+ *bssid_found = TRUE;
empty_line = TRUE;
}
} else {
@@ -2889,6 +2889,8 @@ typedef struct {
const NMMetaAbstractInfo *const *tmpl;
const char *bssid_user;
GArray *out_indices;
+ gint64 rescan_cutoff_msec;
+ guint pending;
} ScanInfo;
typedef struct {
@@ -2900,79 +2902,94 @@ typedef struct {
} WifiListData;
static void
-wifi_list_finish (WifiListData *data)
+wifi_list_finish (WifiListData *wifi_list_data,
+ gboolean force_finished)
{
- ScanInfo *info = data->scan_info;
- NmCli *nmc = info->nmc;
+ ScanInfo *scan_info = wifi_list_data->scan_info;
+ NmCli *nmc = scan_info->nmc;
+ gboolean bssid_found = FALSE;
guint i;
- if (--info->nmc->should_wait == 0) {
- for (i = 0; info->devices[i]; i++) {
- wifi_print_aps (NM_DEVICE_WIFI (info->devices[i]),
- info->nmc,
- info->out_indices,
- info->tmpl,
- info->bssid_user);
- }
- if (nmc->return_value == NMC_RESULT_ERROR_NOT_FOUND) {
- g_string_printf (nmc->return_text, _("Error: Access point with bssid '%s' not found."),
- data->scan_info->bssid_user);
- }
- g_main_loop_quit (loop);
+ if ( !force_finished
+ && scan_info->rescan_cutoff_msec != G_MAXINT64
+ && scan_info->rescan_cutoff_msec > nm_device_wifi_get_last_scan (wifi_list_data->wifi)) {
+ /* wait longer... */
+ return;
+ }
+
+ nm_clear_g_signal_handler (wifi_list_data->wifi, &wifi_list_data->last_scan_id);
+ nm_clear_g_source (&wifi_list_data->timeout_id);
+ nm_clear_g_cancellable (&wifi_list_data->scan_cancellable);
+ nm_g_slice_free (wifi_list_data);
+
+ if (--scan_info->pending > 0)
+ return;
+
+ for (i = 0; scan_info->devices[i]; i++) {
+ wifi_print_aps (NM_DEVICE_WIFI (scan_info->devices[i]),
+ scan_info->nmc,
+ scan_info->out_indices,
+ scan_info->tmpl,
+ scan_info->bssid_user,
+ &bssid_found);
}
- g_signal_handler_disconnect (data->wifi, data->last_scan_id);
- nm_clear_g_source (&data->timeout_id);
- nm_clear_g_cancellable (&data->scan_cancellable);
- nm_g_slice_free (data);
-
- if (info->nmc->should_wait == 0) {
- for (i = 0; info->devices[i]; i++)
- g_object_unref (info->devices[i]);
- g_free (info->devices);
- g_array_unref (info->out_indices);
- nm_g_slice_free (info);
+ if ( scan_info->bssid_user
+ && !bssid_found) {
+ nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND;
+ g_string_printf (nmc->return_text, _("Error: Access point with bssid '%s' not found."),
+ scan_info->bssid_user);
}
+
+ for (i = 0; scan_info->devices[i]; i++)
+ g_object_unref (scan_info->devices[i]);
+ g_free (scan_info->devices);
+ g_array_unref (scan_info->out_indices);
+ nm_g_slice_free (scan_info);
+
+ scan_info->nmc->should_wait--;
+ g_main_loop_quit (loop);
}
static void
wifi_last_scan_updated (GObject *gobject, GParamSpec *pspec, gpointer user_data)
{
- WifiListData *data = user_data;
-
- wifi_list_finish (data);
+ wifi_list_finish (user_data, FALSE);
}
static void
wifi_list_rescan_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
NMDeviceWifi *wifi = NM_DEVICE_WIFI (source_object);
- WifiListData *data = user_data;
gs_free_error GError *error = NULL;
+ WifiListData *wifi_list_data;
+ gboolean force_finished;
- if (!nm_device_wifi_request_scan_finish (wifi, res, &error)) {
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- return;
+ nm_device_wifi_request_scan_finish (wifi, res, &error);
+ if (nm_utils_error_is_cancelled (error))
+ return;
- if (g_error_matches (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_ALLOWED)) {
- /* This likely means that scanning is already in progress. There's
- * a good chance we'll get updated results soon; wait for them. */
- return;
- }
+ if (g_error_matches (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_ALLOWED)) {
+ /* This likely means that scanning is already in progress. There's
+ * a good chance we'll get updated results soon; wait for them. */
+ force_finished = FALSE;
+ } else if (error)
+ force_finished = TRUE;
+ else
+ force_finished = FALSE;
- /* Scanning could not be initiated for unknown reason,
- * no point in waiting for results. */
- wifi_list_finish (data);
- }
+ wifi_list_data = user_data;
+ g_clear_object (&wifi_list_data->scan_cancellable);
+ wifi_list_finish (wifi_list_data, force_finished);
}
static gboolean
wifi_list_scan_timeout (gpointer user_data)
{
- WifiListData *data = user_data;
-
- wifi_list_finish (data);
+ WifiListData *wifi_list_data = user_data;
+ wifi_list_data->timeout_id = 0;
+ wifi_list_finish (user_data, TRUE);
return G_SOURCE_REMOVE;
}
@@ -3009,10 +3026,8 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
const NMMetaAbstractInfo *const*tmpl;
gs_unref_array GArray *out_indices = NULL;
int option;
- guint64 rescan_cutoff;
- NMDeviceWifi *wifi;
+ gint64 rescan_cutoff_msec;
ScanInfo *scan_info = NULL;
- WifiListData *data;
gboolean ifname_handled;
NMDevice *ifname_handled_candidate;
guint i, j;
@@ -3043,8 +3058,6 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
bssid_user = *argv;
if (argc == 1 && nmc->complete)
complete_aps (devices, NULL, bssid_user, NULL);
- /* We'll switch this to NMC_RESULT_SUCCESS if we find an access point. */
- nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND;
break;
case 4: /* --rescan */
argc--;
@@ -3086,13 +3099,13 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
return NMC_RESULT_ERROR_USER_INPUT;
}
- if (rescan == NULL || strcmp (rescan, "auto") == 0) {
- rescan_cutoff = NM_MAX (nm_utils_get_timestamp_msec () - 30 * NM_UTILS_MSEC_PER_SEC, 0);
- } else if (strcmp (rescan, "no") == 0) {
- rescan_cutoff = 0;
- } else if (strcmp (rescan, "yes") == 0) {
- rescan_cutoff = -1;
- } else {
+ if (NM_IN_STRSET (rescan, NULL, "auto"))
+ rescan_cutoff_msec = nm_utils_get_timestamp_msec () - (30 * NM_UTILS_MSEC_PER_SEC);
+ else if (nm_streq (rescan, "no"))
+ rescan_cutoff_msec = G_MININT64;
+ else if (nm_streq (rescan, "yes"))
+ rescan_cutoff_msec = G_MAXINT64;
+ else {
g_string_printf (nmc->return_text, _("Error: invalid rescan argument: '%s' not among [auto, no, yes]"), rescan);
return NMC_RESULT_ERROR_USER_INPUT;
}
@@ -3146,57 +3159,52 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
return NMC_RESULT_ERROR_NOT_FOUND;
}
- /* Start a new scan for devices that need it */
- for (i = 0; devices[i]; i++) {
- wifi = (NMDeviceWifi *) devices[i];
- g_object_ref (wifi);
+ scan_info = g_slice_new (ScanInfo);
+ *scan_info = (ScanInfo) {
+ .out_indices = g_array_ref (out_indices),
+ .tmpl = tmpl,
+ .bssid_user = bssid_user,
+ .nmc = nmc,
+ .rescan_cutoff_msec = rescan_cutoff_msec,
+ };
- if ( rescan_cutoff == 0
- || ( rescan_cutoff > 0
- && nm_device_wifi_get_last_scan (wifi) >= rescan_cutoff))
- continue;
+ for (i = 0; devices[i]; i++)
+ g_object_ref (devices[i]);
- if (!scan_info) {
- scan_info = g_slice_new (ScanInfo);
- *scan_info = (ScanInfo) {
- .out_indices = g_array_ref (out_indices),
- .tmpl = tmpl,
- .bssid_user = bssid_user,
- .nmc = nmc,
- };
- }
+ for (i = 0; devices[i]; i++) {
+ NMDeviceWifi *wifi = NM_DEVICE_WIFI (devices[i]);
+ WifiListData *wifi_list_data;
+ int timeout_msec;
- nmc->should_wait++;
+ if (rescan_cutoff_msec <= nm_device_wifi_get_last_scan (wifi))
+ timeout_msec = 0;
+ else
+ timeout_msec = 15000;
- data = g_slice_new (WifiListData);
- *data = (WifiListData) {
+ wifi_list_data = g_slice_new (WifiListData);
+ *wifi_list_data = (WifiListData) {
.wifi = wifi,
.scan_info = scan_info,
- .last_scan_id = g_signal_connect (wifi,
- "notify::" NM_DEVICE_WIFI_LAST_SCAN,
- G_CALLBACK (wifi_last_scan_updated),
- data),
- .scan_cancellable = g_cancellable_new (),
- .timeout_id = g_timeout_add_seconds (15,
- wifi_list_scan_timeout,
- data),
+ .timeout_id = g_timeout_add (timeout_msec,
+ wifi_list_scan_timeout,
+ wifi_list_data),
};
- nm_device_wifi_request_scan_async (wifi, data->scan_cancellable, wifi_list_rescan_cb, data);
- }
+ scan_info->pending++;
- if (scan_info) {
- scan_info->devices = g_steal_pointer (&devices);
- } else {
- /* Print results right away if no scan is pending */
- for (i = 0; devices[i]; i++) {
- wifi_print_aps (NM_DEVICE_WIFI (devices[i]),
- nmc, out_indices,
- tmpl, bssid_user);
- g_object_unref (devices[i]);
+ if (timeout_msec > 0) {
+ wifi_list_data->last_scan_id = g_signal_connect (wifi,
+ "notify::" NM_DEVICE_WIFI_LAST_SCAN,
+ G_CALLBACK (wifi_last_scan_updated),
+ wifi_list_data),
+ wifi_list_data->scan_cancellable = g_cancellable_new (),
+ nm_device_wifi_request_scan_async (wifi, wifi_list_data->scan_cancellable, wifi_list_rescan_cb, wifi_list_data);
}
}
+ scan_info->devices = g_steal_pointer (&devices);
+
+ nmc->should_wait++;
return nmc->return_value;
}