mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-05 10:20:14 +01:00
merge: add 'nmcli device wifi hotspot' command (bgo #756081)
Synopsis:
nmcli device wifi hotspot [ifname <ifname>] [con-name <name>] [ssid <SSID>]
[band a|bg] [channel <channel>]
[password <password>] [--show-password]
https://bugzilla.gnome.org/show_bug.cgi?id=756081
This commit is contained in:
commit
2b4b78eba1
6 changed files with 451 additions and 33 deletions
|
|
@ -1011,6 +1011,29 @@ nmc_secrets_requested (NMSecretAgentSimple *agent,
|
|||
}
|
||||
}
|
||||
|
||||
char *
|
||||
nmc_unique_connection_name (const GPtrArray *connections, const char *try_name)
|
||||
{
|
||||
NMConnection *connection;
|
||||
const char *name;
|
||||
char *new_name;
|
||||
unsigned int num = 1;
|
||||
int i = 0;
|
||||
|
||||
new_name = g_strdup (try_name);
|
||||
while (i < connections->len) {
|
||||
connection = NM_CONNECTION (connections->pdata[i]);
|
||||
|
||||
name = nm_connection_get_id (connection);
|
||||
if (g_strcmp0 (new_name, name) == 0) {
|
||||
g_free (new_name);
|
||||
new_name = g_strdup_printf ("%s-%d", try_name, num++);
|
||||
i = 0;
|
||||
} else
|
||||
i++;
|
||||
}
|
||||
return new_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* nmc_cleanup_readline:
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ void nmc_secrets_requested (NMSecretAgentSimple *agent,
|
|||
GPtrArray *secrets,
|
||||
gpointer user_data);
|
||||
|
||||
char *nmc_unique_connection_name (const GPtrArray *connections,
|
||||
const char *try_name);
|
||||
|
||||
void nmc_cleanup_readline (void);
|
||||
char *nmc_readline (const char *prompt_fmt, ...) G_GNUC_PRINTF (1, 2);
|
||||
char *nmc_rl_gen_func_basic (const char *text, int state, const char **words);
|
||||
|
|
|
|||
|
|
@ -5810,30 +5810,6 @@ cleanup_bridge_slave:
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static char *
|
||||
unique_connection_name (const GPtrArray *connections, const char *try_name)
|
||||
{
|
||||
NMConnection *connection;
|
||||
const char *name;
|
||||
char *new_name;
|
||||
unsigned int num = 1;
|
||||
int i = 0;
|
||||
|
||||
new_name = g_strdup (try_name);
|
||||
while (i < connections->len) {
|
||||
connection = NM_CONNECTION (connections->pdata[i]);
|
||||
|
||||
name = nm_connection_get_id (connection);
|
||||
if (g_strcmp0 (new_name, name) == 0) {
|
||||
g_free (new_name);
|
||||
new_name = g_strdup_printf ("%s-%d", try_name, num++);
|
||||
i = 0;
|
||||
} else
|
||||
i++;
|
||||
}
|
||||
return new_name;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
NmCli *nmc;
|
||||
char *con_name;
|
||||
|
|
@ -6180,7 +6156,7 @@ do_connection_add (NmCli *nmc, int argc, char **argv)
|
|||
char *try_name = ifname ?
|
||||
g_strdup_printf ("%s-%s", get_name_alias (setting_name, nmc_valid_connection_types), ifname)
|
||||
: g_strdup (get_name_alias (setting_name, nmc_valid_connection_types));
|
||||
default_name = unique_connection_name (nmc->connections, try_name);
|
||||
default_name = nmc_unique_connection_name (nmc->connections, try_name);
|
||||
g_free (try_name);
|
||||
}
|
||||
|
||||
|
|
@ -9015,8 +8991,8 @@ do_connection_edit (NmCli *nmc, int argc, char **argv)
|
|||
if (con_name)
|
||||
default_name = g_strdup (con_name);
|
||||
else
|
||||
default_name = unique_connection_name (nmc->connections,
|
||||
get_name_alias (connection_type, nmc_valid_connection_types));
|
||||
default_name = nmc_unique_connection_name (nmc->connections,
|
||||
get_name_alias (connection_type, nmc_valid_connection_types));
|
||||
|
||||
g_object_set (s_con,
|
||||
NM_SETTING_CONNECTION_ID, default_name,
|
||||
|
|
|
|||
|
|
@ -267,6 +267,8 @@ 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] [hidden yes|no]\n\n"
|
||||
" wifi hotspot [ifname <ifname>] [con-name <name>] [ssid <SSID>] [band a|bg] [channel <channel>]\n\n"
|
||||
" [password <password>] [--show-password]\n\n"
|
||||
" wifi rescan [ifname <ifname>] [[ssid <SSID to scan>] ...]\n\n"
|
||||
));
|
||||
}
|
||||
|
|
@ -371,6 +373,21 @@ 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 := wifi hotspot [ifname <ifname>] [con-name <name>] [ssid <SSID>]\n"
|
||||
" [band a|bg] [channel <channel>] [password <password>]\n"
|
||||
" [--show-password]\n"
|
||||
"\n"
|
||||
"Create a Wi-Fi hotspot. Use 'connection down' or 'device disconnect'\n"
|
||||
"to stop the hotspot.\n"
|
||||
"Parameters of the hotspot can be influenced by the optional parameters:\n"
|
||||
"ifname - Wi-Fi device to use\n"
|
||||
"con-name - name of the created hotspot connection profile\n"
|
||||
"ssid - SSID of the hotspot\n"
|
||||
"band - Wi-Fi band to use\n"
|
||||
"channel - Wi-Fi channel to use\n"
|
||||
"password - password to use for the hotspot\n"
|
||||
"--show-password - tell nmcli to print password to stdout\n"
|
||||
"\n"
|
||||
"ARGUMENTS := rescan [ifname <ifname>] [[ssid <SSID to scan>] ...]\n"
|
||||
"\n"
|
||||
"Request that NetworkManager immediately re-scan for available access points.\n"
|
||||
|
|
@ -1349,6 +1366,7 @@ connected_state_cb (NMDevice *device, NMActiveConnection *active)
|
|||
typedef struct {
|
||||
NmCli *nmc;
|
||||
NMDevice *device;
|
||||
gboolean hotspot;
|
||||
} AddAndActivateInfo;
|
||||
|
||||
static void
|
||||
|
|
@ -1366,8 +1384,12 @@ add_and_activate_cb (GObject *client,
|
|||
active = nm_client_add_and_activate_connection_finish (NM_CLIENT (client), result, &error);
|
||||
|
||||
if (error) {
|
||||
g_string_printf (nmc->return_text, _("Error: Failed to add/activate new connection: %s"),
|
||||
error->message);
|
||||
if (info->hotspot)
|
||||
g_string_printf (nmc->return_text, _("Error: Failed to setup a Wi-Fi hotspot: %s"),
|
||||
error->message);
|
||||
else
|
||||
g_string_printf (nmc->return_text, _("Error: Failed to add/activate new connection: %s"),
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION;
|
||||
quit ();
|
||||
|
|
@ -1375,7 +1397,10 @@ add_and_activate_cb (GObject *client,
|
|||
state = nm_active_connection_get_state (active);
|
||||
|
||||
if (state == NM_ACTIVE_CONNECTION_STATE_UNKNOWN) {
|
||||
g_string_printf (nmc->return_text, _("Error: Failed to add/activate new connection: Unknown error"));
|
||||
if (info->hotspot)
|
||||
g_string_printf (nmc->return_text, _("Error: Failed to setup a Wi-Fi hotspot"));
|
||||
else
|
||||
g_string_printf (nmc->return_text, _("Error: Failed to add/activate new connection: Unknown error"));
|
||||
nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION;
|
||||
g_object_unref (active);
|
||||
quit ();
|
||||
|
|
@ -1386,8 +1411,12 @@ add_and_activate_cb (GObject *client,
|
|||
if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
|
||||
if (nmc->print_output == NMC_PRINT_PRETTY)
|
||||
nmc_terminal_erase_line ();
|
||||
g_print (_("Connection with UUID '%s' created and activated on device '%s'\n"),
|
||||
nm_active_connection_get_uuid (active), nm_device_get_iface (device));
|
||||
if (info->hotspot)
|
||||
g_print (_("Connection with UUID '%s' created and activated on device '%s'\n"),
|
||||
nm_active_connection_get_uuid (active), nm_device_get_iface (device));
|
||||
else
|
||||
g_print (_("Hotspot '%s' activated on device '%s'\n"),
|
||||
nm_active_connection_get_id (active), nm_device_get_iface (device));
|
||||
}
|
||||
g_object_unref (active);
|
||||
quit ();
|
||||
|
|
@ -1566,6 +1595,7 @@ do_device_connect (NmCli *nmc, int argc, char **argv)
|
|||
info = g_malloc0 (sizeof (AddAndActivateInfo));
|
||||
info->nmc = nmc;
|
||||
info->device = device;
|
||||
info->hotspot = FALSE;
|
||||
|
||||
nm_client_activate_connection_async (nmc->client,
|
||||
NULL, /* let NM find a connection automatically */
|
||||
|
|
@ -2659,6 +2689,7 @@ do_device_wifi_connect_network (NmCli *nmc, int argc, char **argv)
|
|||
info = g_malloc0 (sizeof (AddAndActivateInfo));
|
||||
info->nmc = nmc;
|
||||
info->device = device;
|
||||
info->hotspot = FALSE;
|
||||
|
||||
nm_client_add_and_activate_connection_async (nmc->client,
|
||||
connection,
|
||||
|
|
@ -2679,6 +2710,342 @@ error:
|
|||
return nmc->return_value;
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
generate_ssid_for_hotspot (const char *ssid)
|
||||
{
|
||||
GBytes *ssid_bytes;
|
||||
char *hotspot_ssid = NULL;
|
||||
|
||||
if (!ssid) {
|
||||
hotspot_ssid = g_strdup_printf ("Hotspot-%s", g_get_host_name ());
|
||||
if (strlen (hotspot_ssid) > 32)
|
||||
hotspot_ssid[32] = '\0';
|
||||
ssid = hotspot_ssid;
|
||||
}
|
||||
ssid_bytes = g_bytes_new (ssid, strlen (ssid));
|
||||
g_free (hotspot_ssid);
|
||||
return ssid_bytes;
|
||||
}
|
||||
|
||||
#define WPA_PASSKEY_SIZE 8
|
||||
static void
|
||||
generate_wpa_key (char *key, size_t len)
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (key);
|
||||
g_return_if_fail (len > WPA_PASSKEY_SIZE);
|
||||
|
||||
/* generate a 8-chars ASCII WPA key */
|
||||
for (i = 0; i < WPA_PASSKEY_SIZE; i++) {
|
||||
int c;
|
||||
c = g_random_int_range (33, 126);
|
||||
/* too many non alphanumeric characters are hard to remember for humans */
|
||||
while (!g_ascii_isalnum (c))
|
||||
c = g_random_int_range (33, 126);
|
||||
|
||||
key[i] = (gchar) c;
|
||||
}
|
||||
key[WPA_PASSKEY_SIZE] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
generate_wep_key (char *key, size_t len)
|
||||
{
|
||||
int i;
|
||||
const char *hexdigits = "0123456789abcdef";
|
||||
|
||||
g_return_if_fail (key);
|
||||
g_return_if_fail (len > 10);
|
||||
|
||||
/* generate a 10-digit hex WEP key */
|
||||
for (i = 0; i < 10; i++) {
|
||||
int digit;
|
||||
digit = g_random_int_range (0, 16);
|
||||
key[i] = hexdigits[digit];
|
||||
}
|
||||
key[10] = '\0';
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_wireless_security_for_hotspot (NMSettingWirelessSecurity *s_wsec,
|
||||
const char *wifi_mode,
|
||||
NMDeviceWifiCapabilities caps,
|
||||
const char *password,
|
||||
gboolean show_password,
|
||||
GError **error)
|
||||
{
|
||||
char generated_key[11];
|
||||
const char *key;
|
||||
const char *key_mgmt;
|
||||
|
||||
if (g_strcmp0 (wifi_mode, NM_SETTING_WIRELESS_MODE_AP) == 0) {
|
||||
if (caps & NM_WIFI_DEVICE_CAP_RSN) {
|
||||
nm_setting_wireless_security_add_proto (s_wsec, "rsn");
|
||||
nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp");
|
||||
nm_setting_wireless_security_add_group (s_wsec, "ccmp");
|
||||
key_mgmt = "wpa-psk";
|
||||
} else if (caps & NM_WIFI_DEVICE_CAP_WPA) {
|
||||
nm_setting_wireless_security_add_proto (s_wsec, "wpa");
|
||||
nm_setting_wireless_security_add_pairwise (s_wsec, "tkip");
|
||||
nm_setting_wireless_security_add_group (s_wsec, "tkip");
|
||||
key_mgmt = "wpa-psk";
|
||||
} else
|
||||
key_mgmt = "none";
|
||||
} else
|
||||
key_mgmt = "none";
|
||||
|
||||
if (g_strcmp0 (key_mgmt, "wpa-psk") == 0) {
|
||||
/* use WPA */
|
||||
if (password) {
|
||||
if (!nm_utils_wpa_psk_valid (password)) {
|
||||
g_set_error (error, NMCLI_ERROR, 0, _("'%s' is not valid WPA PSK"), password);
|
||||
return FALSE;
|
||||
}
|
||||
key = password;
|
||||
} else {
|
||||
generate_wpa_key (generated_key, sizeof (generated_key));
|
||||
key = generated_key;
|
||||
}
|
||||
g_object_set (s_wsec,
|
||||
NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt,
|
||||
NM_SETTING_WIRELESS_SECURITY_PSK, key,
|
||||
NULL);
|
||||
} else {
|
||||
/* use WEP */
|
||||
if (password) {
|
||||
if (!nm_utils_wep_key_valid (password, NM_WEP_KEY_TYPE_KEY)) {
|
||||
g_set_error (error, NMCLI_ERROR, 0,
|
||||
_("'%s' is not valid WEP key (it should be 5 or 13 ASCII chars)"),
|
||||
password);
|
||||
return FALSE;
|
||||
}
|
||||
key = password;
|
||||
} else {
|
||||
generate_wep_key (generated_key, sizeof (generated_key));
|
||||
key = generated_key;
|
||||
}
|
||||
g_object_set (s_wsec,
|
||||
NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt,
|
||||
NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, key,
|
||||
NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, NM_WEP_KEY_TYPE_KEY,
|
||||
NULL);
|
||||
}
|
||||
if (show_password)
|
||||
g_print (_("Hotspot password: %s\n"), key);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NMCResultCode
|
||||
do_device_wifi_hotspot (NmCli *nmc, int argc, char **argv)
|
||||
{
|
||||
AddAndActivateInfo *info;
|
||||
const char *ifname = NULL;
|
||||
const char *con_name = NULL;
|
||||
char *default_name = NULL;
|
||||
const char *ssid = NULL;
|
||||
const char *wifi_mode;
|
||||
const char *band = NULL;
|
||||
const char *channel = NULL;
|
||||
unsigned long channel_int;
|
||||
const char *password = NULL;
|
||||
gboolean show_password = FALSE;
|
||||
NMDevice *device = NULL;
|
||||
int devices_idx;
|
||||
const GPtrArray *devices;
|
||||
NMDeviceWifiCapabilities caps;
|
||||
NMConnection *connection = NULL;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingWireless *s_wifi;
|
||||
NMSettingWirelessSecurity *s_wsec;
|
||||
NMSettingIPConfig *s_ip4, *s_ip6;
|
||||
GBytes *ssid_bytes;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Set default timeout waiting for operation completion. */
|
||||
if (nmc->timeout == -1)
|
||||
nmc->timeout = 60;
|
||||
|
||||
while (argc > 0) {
|
||||
if (strcmp (*argv, "ifname") == 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;
|
||||
}
|
||||
ifname = *argv;
|
||||
} else if (strcmp (*argv, "con-name") == 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;
|
||||
}
|
||||
con_name = *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;
|
||||
}
|
||||
ssid = *argv;
|
||||
if (strlen (ssid) > 32) {
|
||||
g_string_printf (nmc->return_text, _("Error: ssid is too long."));
|
||||
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
||||
goto error;
|
||||
}
|
||||
} else if (strcmp (*argv, "band") == 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;
|
||||
}
|
||||
band = *argv;
|
||||
if (strcmp (band, "a") && strcmp (band, "bg")) {
|
||||
g_string_printf (nmc->return_text, _("Error: band argument value '%s' is invalid; use 'a' or 'bg'."),
|
||||
band);
|
||||
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
||||
goto error;
|
||||
}
|
||||
} else if (strcmp (*argv, "channel") == 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;
|
||||
}
|
||||
channel = *argv;
|
||||
} else if (strcmp (*argv, "password") == 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;
|
||||
}
|
||||
password = *argv;
|
||||
} else if (nmc_arg_is_option (*argv, "show-password")) {
|
||||
show_password = TRUE;
|
||||
} else {
|
||||
g_string_printf (nmc->return_text, _("Error: Unknown parameter %s."), *argv);
|
||||
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
||||
goto error;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
/* Verify band and channel parameters */
|
||||
if (!channel) {
|
||||
if (g_strcmp0 (band, "bg") == 0)
|
||||
channel = "1";
|
||||
if (g_strcmp0 (band, "a") == 0)
|
||||
channel = "7";
|
||||
}
|
||||
if (channel) {
|
||||
if (!band) {
|
||||
g_string_printf (nmc->return_text, _("Error: channel requires band too."));
|
||||
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
||||
goto error;
|
||||
}
|
||||
if ( !nmc_string_to_uint (channel, TRUE, 1, 5825, &channel_int)
|
||||
|| !nm_utils_wifi_is_channel_valid (channel_int, band)) {
|
||||
g_string_printf (nmc->return_text, _("Error: channel '%s' not valid for band '%s'."),
|
||||
channel, band);
|
||||
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find Wi-Fi device. When no ifname is provided, the first Wi-Fi is used. */
|
||||
devices = nm_client_get_devices (nmc->client);
|
||||
devices_idx = 0;
|
||||
device = find_wifi_device_by_iface (devices, ifname, &devices_idx);
|
||||
|
||||
if (!device) {
|
||||
if (ifname)
|
||||
g_string_printf (nmc->return_text, _("Error: Device '%s' is not a Wi-Fi device."), ifname);
|
||||
else
|
||||
g_string_printf (nmc->return_text, _("Error: No Wi-Fi device found."));
|
||||
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Check device supported mode */
|
||||
caps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (device));
|
||||
if (caps & NM_WIFI_DEVICE_CAP_AP)
|
||||
wifi_mode = NM_SETTING_WIRELESS_MODE_AP;
|
||||
else if (caps & NM_WIFI_DEVICE_CAP_ADHOC)
|
||||
wifi_mode = NM_SETTING_WIRELESS_MODE_ADHOC;
|
||||
else {
|
||||
g_string_printf (nmc->return_text, _("Error: Device '%s' supports neither AP nor Ad-Hoc mode."),
|
||||
nm_device_get_iface (device));
|
||||
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Create a connection with appropriate parameters */
|
||||
connection = nm_simple_connection_new ();
|
||||
s_con = (NMSettingConnection *) nm_setting_connection_new ();
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_con));
|
||||
if (!con_name)
|
||||
con_name = default_name = nmc_unique_connection_name (nm_client_get_connections (nmc->client), "Hotspot");
|
||||
g_object_set (s_con,
|
||||
NM_SETTING_CONNECTION_ID, con_name,
|
||||
NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
|
||||
NULL);
|
||||
g_free (default_name);
|
||||
|
||||
s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_wifi));
|
||||
ssid_bytes = generate_ssid_for_hotspot (ssid);
|
||||
g_object_set (s_wifi, NM_SETTING_WIRELESS_MODE, wifi_mode,
|
||||
NM_SETTING_WIRELESS_SSID, ssid_bytes,
|
||||
NULL);
|
||||
g_bytes_unref (ssid_bytes);
|
||||
if (channel)
|
||||
g_object_set (s_wifi,
|
||||
NM_SETTING_WIRELESS_CHANNEL, (guint32) channel_int,
|
||||
NM_SETTING_WIRELESS_BAND, band,
|
||||
NULL);
|
||||
|
||||
s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_wsec));
|
||||
if (!set_wireless_security_for_hotspot (s_wsec, wifi_mode, caps, password, show_password, &error)) {
|
||||
g_object_unref (connection);
|
||||
g_string_printf (nmc->return_text, _("Error: Invalid 'password': %s."), error->message);
|
||||
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
||||
g_clear_error (&error);
|
||||
goto error;
|
||||
}
|
||||
|
||||
s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new ();
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_ip4));
|
||||
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_SHARED, NULL);
|
||||
|
||||
s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new ();
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_ip6));
|
||||
g_object_set (s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
|
||||
|
||||
/* Activate the connection now */
|
||||
nmc->nowait_flag = (nmc->timeout == 0);
|
||||
nmc->should_wait = TRUE;
|
||||
|
||||
info = g_malloc0 (sizeof (AddAndActivateInfo));
|
||||
info->nmc = nmc;
|
||||
info->device = device;
|
||||
info->hotspot = TRUE;
|
||||
|
||||
nm_client_add_and_activate_connection_async (nmc->client,
|
||||
connection,
|
||||
device,
|
||||
NULL,
|
||||
NULL,
|
||||
add_and_activate_cb,
|
||||
info);
|
||||
|
||||
error:
|
||||
return nmc->return_value;
|
||||
}
|
||||
|
||||
static void
|
||||
request_rescan_cb (GObject *object, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
|
|
@ -2791,6 +3158,8 @@ do_device_wifi (NmCli *nmc, int argc, char **argv)
|
|||
nmc->return_value = do_device_wifi_list (nmc, argc-1, argv+1);
|
||||
} else if (matches (*argv, "connect") == 0) {
|
||||
nmc->return_value = do_device_wifi_connect_network (nmc, argc-1, argv+1);
|
||||
} else if (matches (*argv, "hotspot") == 0) {
|
||||
nmc->return_value = do_device_wifi_hotspot (nmc, argc-1, argv+1);
|
||||
} else if (matches (*argv, "rescan") == 0) {
|
||||
nmc->return_value = do_device_wifi_rescan (nmc, argc-1, argv+1);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -512,6 +512,7 @@ _nmcli_compl_ARGS()
|
|||
save| \
|
||||
hidden| \
|
||||
private)
|
||||
show-password)
|
||||
if [[ "${#words[@]}" -eq 2 ]]; then
|
||||
_nmcli_list "yes no"
|
||||
return 0
|
||||
|
|
@ -589,6 +590,12 @@ _nmcli_compl_ARGS()
|
|||
return 0
|
||||
fi
|
||||
;;
|
||||
band)
|
||||
if [[ "${#words[@]}" -eq 2 ]]; then
|
||||
_nmcli_list "a bg"
|
||||
return 0
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
|
|
@ -1317,7 +1324,7 @@ _nmcli()
|
|||
;;
|
||||
w|wi|wif|wifi)
|
||||
if [[ ${#words[@]} -eq 3 ]]; then
|
||||
_nmcli_compl_COMMAND "${words[2]}" list connect rescan
|
||||
_nmcli_compl_COMMAND "${words[2]}" list connect hotspot rescan
|
||||
else
|
||||
case "${words[2]}" in
|
||||
l|li|lis|list)
|
||||
|
|
@ -1338,6 +1345,11 @@ _nmcli()
|
|||
_nmcli_compl_ARGS
|
||||
fi
|
||||
;;
|
||||
h|ho|hot|hots|hotsp|hotspo|hotspot)
|
||||
_nmcli_array_delete_at words 0 2
|
||||
OPTIONS=(ifname con-name ssid band channel password show-password)
|
||||
_nmcli_compl_ARGS
|
||||
;;
|
||||
r|re|res|resc|resca|rescan)
|
||||
_nmcli_array_delete_at words 0 2
|
||||
OPTIONS_REPEATABLE=(ssid)
|
||||
|
|
|
|||
|
|
@ -853,6 +853,36 @@ Otherwise the connection is system\(hywide, which is the default.
|
|||
Otherwise the SSID would not be found and the connection attempt would fail.
|
||||
.RE
|
||||
.TP
|
||||
.B wifi hotspot [ifname <ifname>] [con-name <name>] [ssid <SSID>] [band a|bg] [channel <channel>]
|
||||
.B [password <password>] [--show-password]
|
||||
.br
|
||||
Create a Wi-Fi hotspot. The command creates a hotspot connection profile according to
|
||||
Wi-Fi device capabilities and activates it on the device. The hotspot is secured with WPA
|
||||
if device/driver supports that, otherwise WEP is used.
|
||||
Use \fIconnection down\fP or \fIdevice disconnect\fP to stop the hotspot.
|
||||
.br
|
||||
.RS
|
||||
.PP
|
||||
Parameters of the hotspot can be influenced by the optional parameters:
|
||||
.IP \fIifname\fP 17
|
||||
\(en what Wi-Fi device is used
|
||||
.IP \fIcon-name\fP 17
|
||||
\(en name of the created hotspot connection profile
|
||||
.IP \fIssid\fP 17
|
||||
\(en SSID of the hotspot
|
||||
.IP \fIband\fP 17
|
||||
\(en Wi-Fi band to use
|
||||
.IP \fIchannel\fP 17
|
||||
\(en Wi-Fi channel to use
|
||||
.IP \fIpassword\fP 17
|
||||
\(en password to use for the created hotspot. If not provided,
|
||||
nmcli will generate a password. The password is either WPA
|
||||
pre-shared key or WEP key.
|
||||
.IP \fI--show-password\fP 17
|
||||
\(en tell nmcli to print the password to stdout. It is useful
|
||||
when the user did not provide his own password.
|
||||
.RE
|
||||
.TP
|
||||
.B wifi rescan [ifname <ifname>] [[ssid <SSID>] ...]
|
||||
.br
|
||||
Request that \fINetworkManager\fP immediately re-scan for available access points.
|
||||
|
|
@ -1040,6 +1070,11 @@ using password "caffeine". This is mainly useful when connecting to "Cafe Hotspo
|
|||
the first time. Next time, it is better to use 'nmcli con up id "My cafe"' so that the
|
||||
existing connection profile can be used and no additional is created.
|
||||
|
||||
.IP "\fB\f(CWnmcli dev wifi hotspot -s con-name QuickHotspot\fP\fP"
|
||||
.IP
|
||||
creates a hotspot profile and connects it. Prints the hotspot password the user should use
|
||||
to connect to the hotspot from other devices.
|
||||
|
||||
.IP "\fB\f(CWnmcli connection add type ethernet autoconnect no ifname eth0\fP\fP"
|
||||
.IP
|
||||
non-interactively adds an Ethernet connection tied to eth0 interface with automatic IP configuration (DHCP),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue