From b1f62ce2cd2689da4a9ced04f555779c321eb191 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 (cherry picked from commit e247567d879b314598efc2fe46f2bc8cd309250d) --- 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 cac615cd67..88a73369fe 100644 --- a/clients/cli/devices.c +++ b/clients/cli/devices.c @@ -277,7 +277,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" #if WITH_WIMAX " wimax [list [ifname ] [nsp ]]\n\n" #endif @@ -371,12 +371,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")); } #if WITH_WIMAX @@ -2585,21 +2587,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. */ @@ -2616,12 +2641,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 38d7e58575..02b236f4f3 100644 --- a/clients/cli/nmcli-completion +++ b/clients/cli/nmcli-completion @@ -539,7 +539,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 @@ -678,7 +680,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 + local OPTIONS_UNKNOWN_OPTION OPTIONS_TYPE OPTIONS_TYPED OPTIONS OPTIONS_MANDATORY COMMAND_ARGS_WAIT_OPTIONS OPTIONS_IP OPTIONS_MANDATORY OPTIONS_NEXT_GROUP OPTIONS_REPEATABLE local COMMAND_CONNECTION_TYPE COMMAND_CONNECTION_ID OPTIONS_MANDATORY_IFNAME HELP_ONLY_AS_FIRST local COMMAND_CONNECTION_ACTIVE="" @@ -1254,7 +1256,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 335b65117a..dccdfc07d1 100644 --- a/man/nmcli.1.in +++ b/man/nmcli.1.in @@ -21,7 +21,7 @@ .\" .\" Copyright 2010 - 2014 Red Hat, Inc. .\" -.TH NMCLI "1" "3 December 2014" +.TH NMCLI "1" "12 August 2015" .SH NAME nmcli \- command\(hyline tool for controlling NetworkManager @@ -786,11 +786,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 .B wimax [list [ifname ] [nsp ]]