cli: add 'ssid' parameter for 'nmcli device wifi rescan'
authorJiří Klimeš <jklimes@redhat.com>
Tue, 14 Jul 2015 07:50:56 +0000 (09:50 +0200)
committerJiří Klimeš <jklimes@redhat.com>
Fri, 14 Aug 2015 10:42:15 +0000 (12:42 +0200)
'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
clients/cli/nmcli-completion
man/nmcli.1.in

index c10febd..c6afaa9 100644 (file)
@@ -265,7 +265,7 @@ usage (void)
                      "  wifi [list [ifname <ifname>] [bssid <BSSID>]]\n\n"
                      "  wifi connect <(B)SSID> [password <password>] [wep-key-type key|phrase] [ifname <ifname>]\n"
                      "                         [bssid <BSSID>] [name <name>] [private yes|no]\n\n"
-                     "  wifi rescan [[ifname] <ifname>]\n\n"
+                     "  wifi rescan [ifname <ifname>] [[ssid <SSID to scan>] ...]\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] <ifname>]\n"
+                     "ARGUMENTS := rescan [ifname <ifname>] [[ssid <SSID to scan>] ...]\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;
 }
 
index 4a55f3d..190d0f3 100644 (file)
@@ -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
index 7ab3ef8..a2beba8 100644 (file)
@@ -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] <ifname>]
+.B wifi rescan [ifname <ifname>] [[ssid <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