diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2014-10-31 15:35:20 +0100 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2014-10-31 15:35:20 +0100 |
commit | 1f275a980a4f649d3f8fe21d0e6b54718c404dfc (patch) | |
tree | f259a2b41ee88f226a1f47ce4a4475e3b7f6e016 | |
parent | 48b4f6f8307addb821aea0db22c3a4801cf7a336 (diff) | |
parent | 8b1447a3a413160313bc468f630d453b2be9df8c (diff) | |
download | NetworkManager-1f275a980a4f649d3f8fe21d0e6b54718c404dfc.tar.gz |
Merge branch 'lr/ap'
https://bugzilla.gnome.org/show_bug.cgi?id=738439
-rw-r--r-- | clients/cli/connections.c | 123 | ||||
-rw-r--r-- | clients/cli/nmcli-completion | 11 | ||||
-rw-r--r-- | clients/cli/utils.c | 25 | ||||
-rw-r--r-- | clients/cli/utils.h | 3 | ||||
-rw-r--r-- | man/nmcli.1.in | 2 | ||||
-rw-r--r-- | src/devices/wifi/nm-device-wifi.c | 53 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/reader.c | 4 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/writer.c | 2 |
8 files changed, 172 insertions, 51 deletions
diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 329012a1fd..0901d22720 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -336,7 +336,8 @@ usage_connection_add (void) " wifi: ssid <SSID>\n" " [mac <MAC address>]\n" " [cloned-mac <cloned MAC address>]\n" - " [mtu <MTU>]\n\n" + " [mtu <MTU>]\n" + " [mode infrastructure|ap|adhoc]\n\n" " wimax: [mac <MAC address>]\n" " [nsp <NSP>]\n\n" " pppoe: username <PPPoE username>\n" @@ -2582,29 +2583,66 @@ check_infiniband_p_key (const char *p_key, guint32 *p_key_int, GError **error) return TRUE; } -/* Checks InfiniBand mode. - * It accepts shortcuts and normalizes them ('mode' argument is modified on success). +/** + * check_valid_enumeration: + * @str: string to check against string array @strings + * @strings: string array to check @str againt + * @what: what parameter @str belongs to (used in error message) + * @what_desc: longer description of @what parameter (used in error message) + * @error: location to store an error, or %NULL + * + * Check whether @str is one of the string of @strings array. It accepts + * shortcuts and normalizes them (@str argument is modified on success). + * + * Returns: %TRUE on success, %FALSE on failure */ static gboolean -check_infiniband_mode (char **mode, GError **error) +check_valid_enumeration (char **str, + const char *strings[], + const char *what, + const char *what_desc, + GError **error) { char *tmp; - const char *checked_mode; - const char *modes[] = { "datagram", "connected", NULL }; + const char *checked_str; - if (!mode || !*mode) + if (!str || !*str) return TRUE; - tmp = g_strstrip (g_strdup (*mode)); - checked_mode = nmc_string_is_valid (tmp, modes, NULL); + tmp = g_strstrip (g_strdup (*str)); + checked_str = nmc_string_is_valid (tmp, strings, NULL); g_free (tmp); - if (checked_mode) { - g_free (*mode); - *mode = g_strdup (checked_mode); - } else + if (checked_str) { + g_free (*str); + *str = g_strdup (checked_str); + } else { + char *options; + + options = nmc_util_strv_for_display (strings); g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'mode': '%s' is not a valid InfiniBand transport mode [datagram, connected]."), *mode); - return !!checked_mode; + _("Error: '%s': '%s' is not a valid %s %s."), + what, *str, what_desc, options); + g_free (options); + } + return !!checked_str; +} + +/* Checks Wi-Fi mode. */ +static gboolean +check_wifi_mode (char **mode, GError **error) +{ + const char *modes[] = { "infrastructure", "ap", "adhoc", NULL }; + + return check_valid_enumeration (mode, modes, "mode", _("Wi-Fi mode"), error); +} + +/* Checks InfiniBand mode. */ +static gboolean +check_infiniband_mode (char **mode, GError **error) +{ + const char *modes[] = { "datagram", "connected", NULL }; + + return check_valid_enumeration (mode, modes, "mode", _("InfiniBand transport mode"), error); } static gboolean @@ -2892,10 +2930,9 @@ do_questionnaire_ethernet (gboolean ethernet, char **mtu, char **mac, char **clo { gboolean once_more; GError *error = NULL; - const char *type = ethernet ? _("ethernet") : _("Wi-Fi"); /* Ask for optional arguments */ - if (!want_provide_opt_args (type, 3)) + if (ethernet && !want_provide_opt_args (_("ethernet"), 3)) return; if (!*mtu) { @@ -3010,11 +3047,36 @@ do_questionnaire_infiniband (char **mtu, char **mac, char **mode, char **parent, } } +#define WORD_INFRA "infrastructure" +#define WORD_AP "ap" +#define WORD_ADHOC "adhoc" +#define PROMPT_WIFI_MODE "(" WORD_INFRA "/" WORD_AP "/" WORD_ADHOC ") [" WORD_INFRA "]: " static void -do_questionnaire_wifi (char **mtu, char **mac, char **cloned_mac) +do_questionnaire_wifi (char **mtu, char **mac, char **cloned_mac, char **mode) { - /* At present, the optional Wi-Fi arguments are the same as for ethernet. */ - return do_questionnaire_ethernet (FALSE, mtu, mac, cloned_mac); + gboolean once_more; + GError *error = NULL; + + /* Ask for optional arguments */ + if (!want_provide_opt_args (_("Wi-Fi"), 4)) + return; + + /* Most optional Wi-Fi arguments are the same as for ethernet. */ + do_questionnaire_ethernet (FALSE, mtu, mac, cloned_mac); + + if (!*mode) { + do { + *mode = nmc_readline (_("Mode %s"), PROMPT_WIFI_MODE); + if (!*mode) + *mode = g_strdup ("infrastructure"); + once_more = !check_wifi_mode (mode, &error); + if (once_more) { + g_print ("%s\n", error->message); + g_clear_error (&error); + g_free (*mode); + } + } while (once_more); + } } static void @@ -3815,10 +3877,13 @@ cleanup_ib: char *mac = NULL; const char *cloned_mac_c = NULL; char *cloned_mac = NULL; + const char *mode_c = NULL; + char *mode = NULL; nmc_arg_t exp_args[] = { {"ssid", TRUE, &ssid, !ask}, {"mtu", TRUE, &mtu_c, FALSE}, {"mac", TRUE, &mac_c, FALSE}, {"cloned-mac", TRUE, &cloned_mac_c, FALSE}, + {"mode", TRUE, &mode_c, FALSE}, {NULL} }; if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) @@ -3836,8 +3901,9 @@ cleanup_ib: mtu = mtu_c ? g_strdup (mtu_c) : NULL; mac = mac_c ? g_strdup (mac_c) : NULL; cloned_mac = cloned_mac_c ? g_strdup (cloned_mac_c) : NULL; + mode = mode_c ? g_strdup (mode_c) : NULL; if (ask) - do_questionnaire_wifi (&mtu, &mac, &cloned_mac); + do_questionnaire_wifi (&mtu, &mac, &cloned_mac, &mode); if (!check_and_convert_mtu (mtu, &mtu_int, error)) goto cleanup_wifi; @@ -3845,6 +3911,8 @@ cleanup_ib: goto cleanup_wifi; if (!check_mac (cloned_mac, ARPHRD_ETHER, "cloned-mac", error)) goto cleanup_wifi; + if (!check_wifi_mode (&mode, error)) + goto cleanup_wifi; /* Add wifi setting */ s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); @@ -3859,6 +3927,9 @@ cleanup_ib: g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, mac, NULL); if (cloned_mac) g_object_set (s_wifi, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, cloned_mac, NULL); + if (mode) + g_object_set (s_wifi, NM_SETTING_WIRELESS_MODE, mode, NULL); + g_bytes_unref (ssid_bytes); success = TRUE; @@ -3867,6 +3938,7 @@ cleanup_wifi: g_free (mtu); g_free (mac); g_free (cloned_mac); + g_free (mode); if (!success) return FALSE; @@ -5022,6 +5094,13 @@ gen_func_bool_values_l10n (const char *text, int state) } static char * +gen_func_wifi_mode (const char *text, int state) +{ + const char *words[] = { "infrastructure", "ap", "adhoc", NULL }; + return nmc_rl_gen_func_basic (text, state, words); +} + +static char * gen_func_ib_type (const char *text, int state) { const char *words[] = { "datagram", "connected", NULL }; @@ -5127,6 +5206,8 @@ nmcli_con_add_tab_completion (const char *text, int start, int end) || g_str_has_suffix (rl_prompt, prompt_yes_no (FALSE, NULL)) || g_str_has_suffix (rl_prompt, prompt_yes_no (FALSE, ":"))) generator_func = gen_func_bool_values_l10n; + else if (g_str_has_suffix (rl_prompt, PROMPT_WIFI_MODE)) + generator_func = gen_func_wifi_mode; else if (g_str_has_suffix (rl_prompt, PROMPT_IB_MODE)) generator_func = gen_func_ib_type; else if (g_str_has_suffix (rl_prompt, PROMPT_BT_TYPE)) diff --git a/clients/cli/nmcli-completion b/clients/cli/nmcli-completion index 3017dc40b3..2080828339 100644 --- a/clients/cli/nmcli-completion +++ b/clients/cli/nmcli-completion @@ -410,7 +410,14 @@ _nmcli_compl_ARGS() ;; mode) if [[ "${#words[@]}" -eq 2 ]]; then - _nmcli_list "balance-rr active-backup balance-xor broadcast 802.3ad balance-tlb balance-alb" + case "$OPTIONS_TYPE" in + "wifi") + _nmcli_list "infrastructure ap adhoc" + ;; + "bond"| \ + *) + _nmcli_list "balance-rr active-backup balance-xor broadcast 802.3ad balance-tlb balance-alb" + esac return 0 fi ;; @@ -918,7 +925,7 @@ _nmcli() 802-11-w|802-11-wi|802-11-wir|802-11-wire|802-11-wirel|802-11-wirele|802-11-wireles|802-11-wireless| \ wif|wifi) OPTIONS_TYPE=wifi - OPTIONS_TYPED=(ssid mac cloned-mac mtu) + OPTIONS_TYPED=(ssid mac cloned-mac mtu mode) OPTIONS_MANDATORY=(ssid) ;; wim|wima|wimax) diff --git a/clients/cli/utils.c b/clients/cli/utils.c index 3152fe4de2..cb8fbf018a 100644 --- a/clients/cli/utils.c +++ b/clients/cli/utils.c @@ -541,6 +541,31 @@ nmc_util_strv_to_slist (char **strv) } /* + * Convert string array (char **) to description string in the form of: + * "[string1, string2, ]" + * + * Returns: a newly allocated string. Caller must free it with g_free(). + */ +char * +nmc_util_strv_for_display (const char **strv) +{ + GString *result; + guint i = 0; + + result = g_string_sized_new (150); + g_string_append_c (result, '['); + while (strv && strv[i]) { + if (result->len > 1) + g_string_append (result, ", "); + g_string_append (result, strv[i]); + i++; + } + g_string_append_c (result, ']'); + + return g_string_free (result, FALSE); +} + +/* * Wrapper function for g_strsplit_set() that removes empty strings * from the vector as they are not useful in most cases. */ diff --git a/clients/cli/utils.h b/clients/cli/utils.h index ea59c4ed55..fc43b0ed92 100644 --- a/clients/cli/utils.h +++ b/clients/cli/utils.h @@ -14,7 +14,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2010 - 2014 Red Hat, Inc. + * Copyright 2010 - 2014 Red Hat, Inc. */ #ifndef NMC_UTILS_H @@ -72,6 +72,7 @@ char *nmc_get_user_input (const char *ask_str); int nmc_string_to_arg_array (const char *line, const char *delim, char ***argv, int *argc); const char *nmc_string_is_valid (const char *input, const char **allowed, GError **error); GSList *nmc_util_strv_to_slist (char **strv); +char * nmc_util_strv_for_display (const char **strv); char **nmc_strsplit_set (const char *str, const char *delimiter, int max_tokens); int nmc_string_screen_width (const char *start, const char *end); void set_val_str (NmcOutputField fields_array[], guint32 index, char *value); diff --git a/man/nmcli.1.in b/man/nmcli.1.in index b662c4a82e..109317f768 100644 --- a/man/nmcli.1.in +++ b/man/nmcli.1.in @@ -418,6 +418,8 @@ Note: use quotes around \fB*\fP to suppress shell expansion. \(en MAC address of the device this connection is locked to .IP "\fI[cloned-mac <cloned MAC address>]\fP" 42 \(en cloned MAC +.IP "\fI[mode infrastructure|ap|adhoc]\fP" 42 +\(en Wi-Fi network mode. If blank, \fIinfrastructure\fP is assumed. .IP "\fI[mtu <MTU>]\fP" 42 \(en MTU .RE diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 51cc8c0358..1210106a0e 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -1036,35 +1036,37 @@ complete_connection (NMDevice *device, nm_connection_add_setting (connection, NM_SETTING (s_wifi)); } - if (ap) { + if (ap) ssid = nm_ap_get_ssid (ap); - - if (ssid == NULL) { - /* The AP must be hidden. Connecting to a WiFi AP requires the SSID - * as part of the initial handshake, so check the connection details - * for the SSID. The AP object will still be used for encryption - * settings and such. - */ - setting_ssid = nm_setting_wireless_get_ssid (s_wifi); - if (setting_ssid) { - ssid = tmp_ssid = g_byte_array_new (); - g_byte_array_append (tmp_ssid, - g_bytes_get_data (setting_ssid, NULL), - g_bytes_get_size (setting_ssid)); - } + if (ssid == NULL) { + /* The AP must be hidden. Connecting to a WiFi AP requires the SSID + * as part of the initial handshake, so check the connection details + * for the SSID. The AP object will still be used for encryption + * settings and such. + */ + setting_ssid = nm_setting_wireless_get_ssid (s_wifi); + if (setting_ssid) { + ssid = tmp_ssid = g_byte_array_new (); + g_byte_array_append (tmp_ssid, + g_bytes_get_data (setting_ssid, NULL), + g_bytes_get_size (setting_ssid)); } + } - if (ssid == NULL) { - /* If there's no SSID on the AP itself, and no SSID in the - * connection data, then we cannot connect at all. Return an error. - */ - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "A 'wireless' setting with a valid SSID is required for hidden access points."); - return FALSE; - } + if (ssid == NULL) { + /* If there's no SSID on the AP itself, and no SSID in the + * connection data, then we cannot connect at all. Return an error. + */ + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + ap + ? "A 'wireless' setting with a valid SSID is required for hidden access points." + : "Cannot create 'wireless' setting due to missing SSID."); + return FALSE; + } + if (ap) { /* If the SSID is a well-known SSID, lock the connection to the AP's * specific BSSID so NM doesn't autoconnect to some random wifi net. */ @@ -1093,7 +1095,6 @@ complete_connection (NMDevice *device, return FALSE; } - g_assert (ssid); str_ssid = nm_utils_ssid_to_utf8 (ssid->data, ssid->len); nm_utils_complete_generic (connection, diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index 60ca5b52c6..6994f6af93 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -3379,11 +3379,13 @@ make_wireless_setting (shvarFile *ifcfg, if (!strcmp (lcase, "ad-hoc")) { mode = "adhoc"; + } else if (!strcmp (lcase, "ap")) { + mode = "ap"; } else if (!strcmp (lcase, "managed") || !strcmp (lcase, "auto")) { mode = "infrastructure"; } else { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid mode '%s' (not 'Ad-Hoc', 'Managed', or 'Auto')", + "Invalid mode '%s' (not 'Ad-Hoc', 'Ap', 'Managed', or 'Auto')", lcase); g_free (lcase); goto error; diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index c088525dac..55dca87c82 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -901,6 +901,8 @@ write_wireless_setting (NMConnection *connection, } else if (!strcmp (mode, "adhoc")) { svSetValue (ifcfg, "MODE", "Ad-Hoc", FALSE); adhoc = TRUE; + } else if (!strcmp (mode, "ap")) { + svSetValue (ifcfg, "MODE", "Ap", FALSE); } else { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Invalid mode '%s' in '%s' setting", |