diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2019-10-30 14:32:46 +0100 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2019-10-30 14:32:46 +0100 |
commit | 35e4e106cb3580bfa65f64c825bd53864ac6483e (patch) | |
tree | 09bac1a5f5a32b794f7711e57cc755061a7a8227 | |
parent | 074e5503d7ff7af853785f4cbb64fbfc43d1ef6a (diff) | |
parent | 9c5ea0917d5121132c4c37c29596f8062ae49b59 (diff) | |
download | NetworkManager-35e4e106cb3580bfa65f64c825bd53864ac6483e.tar.gz |
merge: branch 'lr/hotspot-reuse'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/305
-rw-r--r-- | clients/cli/devices.c | 281 |
1 files changed, 179 insertions, 102 deletions
diff --git a/clients/cli/devices.c b/clients/cli/devices.c index 24689f63da..1c440e487b 100644 --- a/clients/cli/devices.c +++ b/clients/cli/devices.c @@ -3136,6 +3136,38 @@ activate_update2_cb (GObject *source_object, GAsyncResult *res, gpointer user_da info); } +static void +save_and_activate_connection (NmCli *nmc, + NMDevice *device, + NMConnection *connection, + gboolean hotspot, + const char *specific_object) +{ + AddAndActivateInfo *info; + + info = add_and_activate_info_new (nmc, device, hotspot, + !NM_IS_REMOTE_CONNECTION (connection), + specific_object); + + if (NM_IS_REMOTE_CONNECTION (connection)) { + nm_remote_connection_update2 (NM_REMOTE_CONNECTION (connection), + nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL), + NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT, + NULL, + NULL, + activate_update2_cb, + info); + } else { + nm_client_add_and_activate_connection_async (nmc->client, + connection, + info->device, + info->specific_object, + NULL, + add_and_activate_cb, + info); + } +} + static NMCResultCode do_device_wifi_connect (NmCli *nmc, int argc, char **argv) { @@ -3144,11 +3176,9 @@ do_device_wifi_connect (NmCli *nmc, int argc, char **argv) NM80211ApFlags ap_flags; NM80211ApSecurityFlags ap_wpa_flags; NM80211ApSecurityFlags ap_rsn_flags; - NMRemoteConnection *remote_con = NULL; - NMConnection *connection = NULL; + gs_unref_object NMConnection *connection = NULL; NMSettingConnection *s_con; NMSettingWireless *s_wifi; - AddAndActivateInfo *info; const char *param_user = NULL; const char *ifname = NULL; const char *bssid = NULL; @@ -3399,7 +3429,7 @@ do_device_wifi_connect (NmCli *nmc, int argc, char **argv) avail_cons = nm_device_get_available_connections (device); for (i = 0; i < avail_cons->len; i++) { - NMRemoteConnection *avail_con = g_ptr_array_index (avail_cons, i); + NMConnection *avail_con = g_ptr_array_index (avail_cons, i); const char *id = nm_connection_get_id (NM_CONNECTION (avail_con)); if (con_name) { @@ -3413,19 +3443,18 @@ do_device_wifi_connect (NmCli *nmc, int argc, char **argv) /* ap has been checked against bssid1, bssid2 and the ssid * and now avail_con has been checked against ap. */ - remote_con = avail_con; - connection = NM_CONNECTION (remote_con); + connection = g_object_ref (avail_con); break; } } - if (name_match && !remote_con) { + if (name_match && !connection) { g_string_printf (nmc->return_text, _("Error: Connection '%s' exists but properties don't match."), con_name); nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; goto finish; } - if (!remote_con) { + if (!connection) { /* If there are some connection data from user, create a connection and * fill them into proper settings. */ if (con_name || private || bssid2_arr || hidden) @@ -3540,25 +3569,8 @@ do_device_wifi_connect (NmCli *nmc, int argc, char **argv) nmc->nowait_flag = (nmc->timeout == 0); nmc->should_wait++; - info = add_and_activate_info_new (nmc, device, FALSE, !remote_con, nm_object_get_path (NM_OBJECT (ap))); - - if (remote_con) { - nm_remote_connection_update2 (remote_con, - nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL), - NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT, - NULL, - NULL, - activate_update2_cb, - info); - } else { - nm_client_add_and_activate_connection_async (nmc->client, - connection, - info->device, - info->specific_object, - NULL, - add_and_activate_cb, - info); - } + save_and_activate_connection (nmc, device, connection, FALSE, + nm_object_get_path (NM_OBJECT (ap))); finish: if (bssid1_arr) @@ -3572,19 +3584,17 @@ finish: } static GBytes * -generate_ssid_for_hotspot (const char *ssid) +generate_ssid_for_hotspot (void) { GBytes *ssid_bytes; - char *hotspot_ssid = NULL; + char *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 = g_strdup_printf ("Hotspot-%s", g_get_host_name ()); + if (strlen (ssid) > 32) + ssid[32] = '\0'; ssid_bytes = g_bytes_new (ssid, strlen (ssid)); - g_free (hotspot_ssid); + g_free (ssid); + return ssid_bytes; } @@ -3698,30 +3708,125 @@ set_wireless_security_for_hotspot (NMSettingWirelessSecurity *s_wsec, return TRUE; } +static NMConnection * +find_hotspot_conn (NMDevice *device, + const GPtrArray *connections, + const char *con_name, + GBytes *ssid_bytes, + const char *wifi_mode, + const char *band, + gint64 channel_int) +{ + NMConnection *connection; + NMSettingWireless *s_wifi; + int i; + + for (i = 0; i < connections->len; i++) { + connection = NM_CONNECTION (connections->pdata[i]); + + s_wifi = nm_connection_get_setting_wireless (connection); + if (!s_wifi) + continue; + + if ( channel_int != -1 + && nm_setting_wireless_get_channel (s_wifi) != channel_int) + continue; + + if (g_strcmp0 (nm_setting_wireless_get_mode (s_wifi), wifi_mode) != 0) + continue; + + if (band && g_strcmp0 (nm_setting_wireless_get_band (s_wifi), band) != 0) + continue; + + if (ssid_bytes && !g_bytes_equal (nm_setting_wireless_get_ssid (s_wifi), ssid_bytes)) + continue; + + if (!nm_device_connection_compatible (device, connection, NULL)) + continue; + + return g_object_ref (connection); + } + + return NULL; +} + +static NMConnection * +create_hotspot_conn (const GPtrArray *connections, + const char *con_name, + GBytes *ssid_bytes, + const char *wifi_mode, + const char *band, + gint64 channel_int) +{ + char *default_name = NULL; + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSettingIPConfig *s_ip4, *s_ip6; + NMSettingProxy *s_proxy; + + 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 (connections, "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)); + + g_object_set (s_wifi, NM_SETTING_WIRELESS_MODE, wifi_mode, + NM_SETTING_WIRELESS_SSID, ssid_bytes, + NULL); + + if (channel_int != -1) { + 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)); + + 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); + + s_proxy = (NMSettingProxy *) nm_setting_proxy_new (); + nm_connection_add_setting (connection, NM_SETTING (s_proxy)); + g_object_set (s_proxy, NM_SETTING_PROXY_METHOD, (int) NM_SETTING_PROXY_METHOD_NONE, NULL); + + return connection; +} + 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; + gs_unref_bytes GBytes *ssid_bytes = NULL; const char *wifi_mode; const char *band = NULL; const char *channel = NULL; - unsigned long channel_int; + gint64 channel_int = -1; const char *password = NULL; gboolean show_password = FALSE; NMDevice *device = NULL; gs_free NMDevice **devices = NULL; NMDeviceWifiCapabilities caps; - NMConnection *connection = NULL; - NMSettingConnection *s_con; - NMSettingWireless *s_wifi; + gs_unref_object NMConnection *connection = NULL; + const GPtrArray *connections; NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4, *s_ip6; - NMSettingProxy *s_proxy; - GBytes *ssid_bytes; GError *error = NULL; /* Set default timeout waiting for operation completion. */ @@ -3762,11 +3867,11 @@ do_device_wifi_hotspot (NmCli *nmc, int argc, char **argv) g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1)); return NMC_RESULT_ERROR_USER_INPUT; } - ssid = *argv; - if (strlen (ssid) > 32) { + if (strlen (*argv) > 32) { g_string_printf (nmc->return_text, _("Error: ssid is too long.")); return NMC_RESULT_ERROR_USER_INPUT; } + ssid_bytes = g_bytes_new (*argv, strlen (*argv)); } else if (strcmp (*argv, "band") == 0) { argc--; argv++; @@ -3822,21 +3927,24 @@ do_device_wifi_hotspot (NmCli *nmc, int argc, char **argv) channel = "7"; } if (channel) { + unsigned long int value; + if (!band) { g_string_printf (nmc->return_text, _("Error: channel requires band too.")); return NMC_RESULT_ERROR_USER_INPUT; } - if ( !nmc_string_to_uint (channel, TRUE, 1, 5825, &channel_int) - || !nm_utils_wifi_is_channel_valid (channel_int, band)) { + if ( !nmc_string_to_uint (channel, TRUE, 1, 5825, &value) + || !nm_utils_wifi_is_channel_valid (value, band)) { g_string_printf (nmc->return_text, _("Error: channel '%s' not valid for band '%s'."), channel, band); return NMC_RESULT_ERROR_USER_INPUT; } + + channel_int = value; } /* Find Wi-Fi device. When no ifname is provided, the first Wi-Fi is used. */ device = find_wifi_device_by_iface (devices, ifname, NULL); - if (!device) { if (ifname) g_string_printf (nmc->return_text, _("Error: Device '%s' is not a Wi-Fi device."), ifname); @@ -3857,65 +3965,34 @@ do_device_wifi_hotspot (NmCli *nmc, int argc, char **argv) return NMC_RESULT_ERROR_UNKNOWN; } - /* 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); - g_clear_error (&error); - return NMC_RESULT_ERROR_UNKNOWN; + connections = nm_client_get_connections (nmc->client); + connection = find_hotspot_conn (device, connections, con_name, ssid_bytes, + wifi_mode, band, channel_int); + if (!connection) { + /* Create a connection with appropriate parameters */ + if (!ssid_bytes) + ssid_bytes = generate_ssid_for_hotspot (); + connection = create_hotspot_conn (connections, con_name, ssid_bytes, + wifi_mode, band, channel_int); } - 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); + if (password || !NM_IS_REMOTE_CONNECTION (connection)) { + s_wsec = nm_connection_get_setting_wireless_security (connection); + g_return_val_if_fail (s_wsec, NMC_RESULT_ERROR_UNKNOWN); - 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); - - s_proxy = (NMSettingProxy *) nm_setting_proxy_new (); - nm_connection_add_setting (connection, NM_SETTING (s_proxy)); - g_object_set (s_proxy, NM_SETTING_PROXY_METHOD, (int) NM_SETTING_PROXY_METHOD_NONE, NULL); + 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); + g_clear_error (&error); + return NMC_RESULT_ERROR_UNKNOWN; + } + } /* Activate the connection now */ nmc->nowait_flag = (nmc->timeout == 0); nmc->should_wait++; - info = add_and_activate_info_new (nmc, device, TRUE, TRUE, NULL); - - nm_client_add_and_activate_connection_async (nmc->client, - connection, - device, - NULL, - NULL, - add_and_activate_cb, - info); + save_and_activate_connection (nmc, device, connection, TRUE, NULL); return nmc->return_value; } |