From e247567d879b314598efc2fe46f2bc8cd309250d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Tue, 14 Jul 2015 09:50:56 +0200 Subject: [PATCH] cli: add 'ssid' parameter for 'nmcli device wifi rescan' 'ssid' can repeat when more SSIDs should be scanned, e.g. $ nmcli dev wifi rescan ssid "hidden cafe" ssid AP12 ssid "my home Wi-Fi" Bash completion fixed by thaller@redhat.com --- clients/cli/devices.c | 62 ++++++++++++++++++++++++++++++------ clients/cli/nmcli-completion | 9 ++++-- man/nmcli.1.in | 10 ++++-- 3 files changed, 66 insertions(+), 15 deletions(-) diff --git a/clients/cli/devices.c b/clients/cli/devices.c index c10febdd9..c6afaa907 100644 --- a/clients/cli/devices.c +++ b/clients/cli/devices.c @@ -265,7 +265,7 @@ usage (void) " wifi [list [ifname ] [bssid ]]\n\n" " wifi connect <(B)SSID> [password ] [wep-key-type key|phrase] [ifname ]\n" " [bssid ] [name ] [private yes|no]\n\n" - " wifi rescan [[ifname] ]\n\n" + " wifi rescan [ifname ] [[ssid ] ...]\n\n" )); } @@ -356,12 +356,14 @@ usage_device_wifi (void) "only open, WEP and WPA-PSK networks are supported at the moment. It is also\n" "assumed that IP configuration is obtained via DHCP.\n" "\n" - "ARGUMENTS := rescan [[ifname] ]\n" + "ARGUMENTS := rescan [ifname ] [[ssid ] ...]\n" "\n" "Request that NetworkManager immediately re-scan for available access points.\n" "NetworkManager scans Wi-Fi networks periodically, but in some cases it might\n" - "be useful to start scanning manually. Note that this command does not show\n" - "the APs, use 'nmcli device wifi list' for that.\n\n")); + "be useful to start scanning manually. 'ssid' allows scanning for a specific\n" + "SSID, which is useful for APs with hidden SSIDs. More 'ssid' parameters can be\n" + "given. Note that this command does not show the APs,\n" + "use 'nmcli device wifi list' for that.\n\n")); } /* quit main loop */ @@ -2510,21 +2512,44 @@ do_device_wifi_rescan (NmCli *nmc, int argc, char **argv) { NMDevice *device; const char *ifname = NULL; + GPtrArray *ssids; const GPtrArray *devices; int devices_idx; + GVariantBuilder builder, array_builder; + GVariant *options; + const char *ssid; + int i; nmc->should_wait = TRUE; + ssids = g_ptr_array_new (); + /* Get the parameters */ - if (argc > 0) { + while (argc > 0) { if (strcmp (*argv, "ifname") == 0) { + if (ifname) { + g_string_printf (nmc->return_text, _("Error: '%s' cannot repeat."), *(argv-1)); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } if (next_arg (&argc, &argv) != 0) { g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1)); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; goto error; } - } - ifname = *argv; + ifname = *argv; + } else if (strcmp (*argv, "ssid") == 0) { + if (next_arg (&argc, &argv) != 0) { + g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1)); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } + g_ptr_array_add (ssids, *argv); + } else + g_printerr (_("Unknown parameter: %s\n"), *argv); + + argc--; + argv++; } /* Find Wi-Fi device to scan on. When no ifname is provided, the first Wi-Fi is used. */ @@ -2541,12 +2566,31 @@ do_device_wifi_rescan (NmCli *nmc, int argc, char **argv) goto error; } - nm_device_wifi_request_scan_async (NM_DEVICE_WIFI (device), NULL, - request_rescan_cb, nmc); + if (ssids->len) { + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aay")); + + for (i = 0; i < ssids->len; i++) { + ssid = g_ptr_array_index (ssids, i); + g_variant_builder_add (&array_builder, "@ay", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, ssid, strlen (ssid), 1)); + } + + g_variant_builder_add (&builder, "{sv}", "ssids", g_variant_builder_end (&array_builder)); + options = g_variant_builder_end (&builder); + + nm_device_wifi_request_scan_options_async (NM_DEVICE_WIFI (device), options, + NULL, request_rescan_cb, nmc); + } else + nm_device_wifi_request_scan_async (NM_DEVICE_WIFI (device), + NULL, request_rescan_cb, nmc); + + g_ptr_array_free (ssids, FALSE); return nmc->return_value; error: nmc->should_wait = FALSE; + g_ptr_array_free (ssids, FALSE); return nmc->return_value; } diff --git a/clients/cli/nmcli-completion b/clients/cli/nmcli-completion index 4a55f3dbc..190d0f3e3 100644 --- a/clients/cli/nmcli-completion +++ b/clients/cli/nmcli-completion @@ -579,7 +579,9 @@ _nmcli_compl_ARGS() # remove the options already seen. for i in ${!OPTIONS[*]}; do if [[ "${OPTIONS[$i]}" = "${REMOVE_OPTIONS[0]}" || "${OPTIONS[$i]}" = "${REMOVE_OPTIONS[1]}" ]]; then - unset OPTIONS[$i] + if ! _nmcli_array_has_value OPTIONS_REPEATABLE "${OPTIONS[$i]}" ; then + unset OPTIONS[$i] + fi fi done for i in ${!OPTIONS_MANDATORY[*]}; do @@ -737,7 +739,7 @@ _nmcli() cur='' fi - local OPTIONS_UNKNOWN_OPTION OPTIONS_TYPE OPTIONS_TYPED OPTIONS OPTIONS_MANDATORY COMMAND_ARGS_WAIT_OPTIONS OPTIONS_IP OPTIONS_MANDATORY OPTIONS_NEXT_GROUP OPTIONS_SEP + local OPTIONS_UNKNOWN_OPTION OPTIONS_TYPE OPTIONS_TYPED OPTIONS OPTIONS_MANDATORY COMMAND_ARGS_WAIT_OPTIONS OPTIONS_IP OPTIONS_MANDATORY OPTIONS_NEXT_GROUP OPTIONS_SEP OPTIONS_REPEATABLE local COMMAND_CONNECTION_TYPE COMMAND_CONNECTION_ID OPTIONS_MANDATORY_IFNAME HELP_ONLY_AS_FIRST local COMMAND_CONNECTION_ACTIVE="" @@ -1293,7 +1295,8 @@ _nmcli() ;; r|re|res|resc|resca|rescan) _nmcli_array_delete_at words 0 2 - OPTIONS=(ifname) + OPTIONS_REPEATABLE=(ssid) + OPTIONS=(ifname ssid) _nmcli_compl_ARGS ;; esac diff --git a/man/nmcli.1.in b/man/nmcli.1.in index 7ab3ef8cd..a2beba86a 100644 --- a/man/nmcli.1.in +++ b/man/nmcli.1.in @@ -21,7 +21,7 @@ .\" .\" Copyright 2010 - 2015 Red Hat, Inc. .\" -.TH NMCLI "1" "19 February 2015" +.TH NMCLI "1" "12 August 2015" .SH NAME nmcli \- command\(hyline tool for controlling NetworkManager @@ -832,11 +832,15 @@ Available options are: Otherwise the connection is system\(hywide, which is the default. .RE .TP -.B wifi rescan [[ifname] ] +.B wifi rescan [ifname ] [[ssid ] ...] .br Request that \fINetworkManager\fP immediately re-scan for available access points. NetworkManager scans Wi\(hyFi networks periodically, but in some cases it can be -useful to start scanning manually (e.g. after resuming the computer). +useful to start scanning manually (e.g. after resuming the computer). By using +\fIssid\fP, it is possible to scan for a specific SSID, which is useful for APs +with hidden SSIDs. You can provide multiple \fIssid\fP parameters in order to +scan more SSIDs. +.br This command does not show the APs, use 'nmcli device wifi list' for that. .TP