summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2014-10-31 15:35:20 +0100
committerLubomir Rintel <lkundrak@v3.sk>2014-10-31 15:35:20 +0100
commit1f275a980a4f649d3f8fe21d0e6b54718c404dfc (patch)
treef259a2b41ee88f226a1f47ce4a4475e3b7f6e016
parent48b4f6f8307addb821aea0db22c3a4801cf7a336 (diff)
parent8b1447a3a413160313bc468f630d453b2be9df8c (diff)
downloadNetworkManager-1f275a980a4f649d3f8fe21d0e6b54718c404dfc.tar.gz
Merge branch 'lr/ap'
https://bugzilla.gnome.org/show_bug.cgi?id=738439
-rw-r--r--clients/cli/connections.c123
-rw-r--r--clients/cli/nmcli-completion11
-rw-r--r--clients/cli/utils.c25
-rw-r--r--clients/cli/utils.h3
-rw-r--r--man/nmcli.1.in2
-rw-r--r--src/devices/wifi/nm-device-wifi.c53
-rw-r--r--src/settings/plugins/ifcfg-rh/reader.c4
-rw-r--r--src/settings/plugins/ifcfg-rh/writer.c2
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",