diff --git a/clients/cli/settings.c b/clients/cli/settings.c index b524e1fe2..71d3713d9 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -1854,14 +1854,19 @@ static char * nmc_property_wireless_get_powersave (NMSetting *setting, NmcPropertyGetType get_type) { NMSettingWireless *s_wireless = NM_SETTING_WIRELESS (setting); - guint powersave = nm_setting_wireless_get_powersave (s_wireless); + NMSettingWirelessPowersave powersave; + gs_free char *str = NULL; + char *ret; - if (powersave == 0) - return g_strdup (_("no")); - else if (powersave == 1) - return g_strdup (_("yes")); - else - return g_strdup_printf (_("yes (%u)"), powersave); + powersave = nm_setting_wireless_get_powersave (s_wireless); + str = nm_utils_enum_to_str (nm_setting_wireless_powersave_get_type (), powersave); + + if (get_type == NMC_PROPERTY_GET_PARSABLE) { + ret = str; + str = NULL; + return ret; + } else + return g_strdup_printf ("%s (%u)", str, powersave); } static char * @@ -4918,20 +4923,33 @@ DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_wireless_remove_mac_address_blacklis static gboolean nmc_property_wireless_set_powersave (NMSetting *setting, const char *prop, const char *val, GError **error) { - unsigned long powersave_int; - gboolean val_bool = FALSE; + NMSettingWirelessPowersave powersave; + gs_free const char **options = NULL; + gs_free char *options_str = NULL; + long int t; + gboolean ret; - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - if (!nmc_string_to_uint (val, TRUE, 0, G_MAXUINT32, &powersave_int)) { - if (!nmc_string_to_bool (val, &val_bool, NULL)) { - g_set_error (error, 1, 0, _("'%s' is not a valid powersave value"), val); + if (nmc_string_to_int_base (val, 0, TRUE, + NM_SETTING_WIRELESS_POWERSAVE_DEFAULT, + NM_SETTING_WIRELESS_POWERSAVE_LAST, + &t)) + powersave = (NMSettingWirelessPowersave) t; + else { + ret = nm_utils_enum_from_str (nm_setting_wireless_powersave_get_type (), + val, + (int *) &powersave, + NULL); + if (!ret) { + options = nm_utils_enum_get_values (nm_setting_wireless_powersave_get_type (), + NM_SETTING_WIRELESS_POWERSAVE_DEFAULT, + NM_SETTING_WIRELESS_POWERSAVE_LAST); + options_str = g_strjoinv (",", (char **) options); + g_set_error (error, 1, 0, _("invalid option '%s', use one of [%s]"), val, options_str); return FALSE; } - powersave_int = val_bool ? 1 : 0; } - g_object_set (setting, prop, (guint32) powersave_int, NULL); + g_object_set (setting, prop, (guint) powersave, NULL); return TRUE; } diff --git a/libnm-core/nm-setting-wireless.c b/libnm-core/nm-setting-wireless.c index 3b2789335..6b9ad0ba1 100644 --- a/libnm-core/nm-setting-wireless.c +++ b/libnm-core/nm-setting-wireless.c @@ -1365,25 +1365,26 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) /** * NMSettingWireless:powersave: * - * If set to %FALSE, Wi-Fi power saving behavior is disabled. If set to - * %TRUE, Wi-Fi power saving behavior is enabled. All other values are - * reserved. Note that even though only boolean values are allowed, the - * property type is an unsigned integer to allow for future expansion. + * One of %NM_SETTING_WIRELESS_POWERSAVE_DISABLE (disable Wi-Fi power + * saving), %NM_SETTING_WIRELESS_POWERSAVE_ENABLE (enable Wi-Fi power + * saving), %NM_SETTING_WIRELESS_POWERSAVE_IGNORE (don't touch currently + * configure setting) or %NM_SETTING_WIRELESS_POWERSAVE_DEFAULT (use the + * globally configured value). All other values are reserved. * * Since: 1.2 **/ /* ---ifcfg-rh--- * property: powersave * variable: POWERSAVE(+) - * default: no + * values: default, ignore, enable, disable * description: Enables or disables Wi-Fi power saving. - * example: POWERSAVE=yes + * example: POWERSAVE=enable * ---end--- */ g_object_class_install_property (object_class, PROP_POWERSAVE, g_param_spec_uint (NM_SETTING_WIRELESS_POWERSAVE, "", "", - 0, G_MAXUINT32, 0, + 0, G_MAXUINT32, NM_SETTING_WIRELESS_POWERSAVE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); diff --git a/libnm-core/nm-setting-wireless.h b/libnm-core/nm-setting-wireless.h index a4c0147f4..606733fa9 100644 --- a/libnm-core/nm-setting-wireless.h +++ b/libnm-core/nm-setting-wireless.h @@ -80,6 +80,25 @@ G_BEGIN_DECLS */ #define NM_SETTING_WIRELESS_MODE_INFRA "infrastructure" +/** + * NMSettingWirelessPowersave: + * @NM_SETTING_WIRELESS_POWERSAVE_DEFAULT: use the default value + * @NM_SETTING_WIRELESS_POWERSAVE_IGNORE: don't touch existing setting + * @NM_SETTING_WIRELESS_POWERSAVE_DISABLE: disable powersave + * @NM_SETTING_WIRELESS_POWERSAVE_ENABLE: enable powersave + * + * These flags indicate whether wireless powersave must be enabled. + **/ +typedef enum { + NM_SETTING_WIRELESS_POWERSAVE_DEFAULT = 0, + NM_SETTING_WIRELESS_POWERSAVE_IGNORE = 1, + NM_SETTING_WIRELESS_POWERSAVE_DISABLE = 2, + NM_SETTING_WIRELESS_POWERSAVE_ENABLE = 3, + _NM_SETTING_WIRELESS_POWERSAVE_NUM, /*< skip >*/ + NM_SETTING_WIRELESS_POWERSAVE_LAST = _NM_SETTING_WIRELESS_POWERSAVE_NUM - 1, /*< skip >*/ +} NMSettingWirelessPowersave; + + struct _NMSettingWireless { NMSetting parent; }; diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 8e01a310f..3867c3df0 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1014,6 +1014,7 @@ global: nm_setting_wired_wake_on_lan_get_type; nm_setting_wireless_get_powersave; nm_setting_wireless_get_mac_address_randomization; + nm_setting_wireless_powersave_get_type; nm_utils_bond_mode_int_to_string; nm_utils_bond_mode_string_to_int; nm_utils_enum_from_str; diff --git a/man/NetworkManager.conf.xml.in b/man/NetworkManager.conf.xml.in index a2bd36e05..75e1d9380 100644 --- a/man/NetworkManager.conf.xml.in +++ b/man/NetworkManager.conf.xml.in @@ -563,6 +563,11 @@ ipv6.ip6-privacy=0 wifi.mac-address-randomization If left unspecified, MAC address randomization is disabled. + + wifi.powersave + If left unspecified, the default value + "ignore" will be used. + diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 63aa6d22b..e4640786b 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -489,8 +489,6 @@ deactivate (NMDevice *device) if (nm_device_get_initial_hw_address (device)) nm_device_set_hw_addr (device, nm_device_get_initial_hw_address (device), "reset", LOGD_WIFI); - nm_platform_wifi_set_powersave (NM_PLATFORM_GET, ifindex, 0); - /* Ensure we're in infrastructure mode after deactivation; some devices * (usually older ones) don't scan well in adhoc mode. */ @@ -2388,6 +2386,38 @@ ensure_hotspot_frequency (NMDeviceWifi *self, nm_ap_set_freq (ap, freq); } +static void +set_powersave (NMDevice *device) +{ + NMDeviceWifi *self = NM_DEVICE_WIFI (device); + NMSettingWireless *s_wireless; + NMSettingWirelessPowersave powersave; + gs_free char *value = NULL; + + s_wireless = (NMSettingWireless *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRELESS); + g_return_if_fail (s_wireless); + + powersave = nm_setting_wireless_get_powersave (s_wireless); + if (powersave == NM_SETTING_WIRELESS_POWERSAVE_DEFAULT) { + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "wifi.powersave", + device); + powersave = _nm_utils_ascii_str_to_int64 (value, 10, + NM_SETTING_WIRELESS_POWERSAVE_IGNORE, + NM_SETTING_WIRELESS_POWERSAVE_ENABLE, + NM_SETTING_WIRELESS_POWERSAVE_IGNORE); + } + + _LOGT (LOGD_WIFI, "powersave is set to %u", (unsigned int) powersave); + + if (powersave == NM_SETTING_WIRELESS_POWERSAVE_IGNORE) + return; + + nm_platform_wifi_set_powersave (NM_PLATFORM_GET, + nm_device_get_ifindex (device), + powersave == NM_SETTING_WIRELESS_POWERSAVE_ENABLE); +} + static NMActStageReturn act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) { @@ -2454,11 +2484,8 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) if ((nm_ap_get_mode (ap) == NM_802_11_MODE_ADHOC) || nm_ap_is_hotspot (ap)) ensure_hotspot_frequency (self, s_wireless, ap); - if (nm_ap_get_mode (ap) == NM_802_11_MODE_INFRA) { - nm_platform_wifi_set_powersave (NM_PLATFORM_GET, - nm_device_get_ifindex (device), - nm_setting_wireless_get_powersave (s_wireless)); - } + if (nm_ap_get_mode (ap) == NM_802_11_MODE_INFRA) + set_powersave (device); /* Build up the supplicant configuration */ config = build_supplicant_config (self, connection, nm_ap_get_freq (ap), &error); diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index 7596ba29b..042ad9a03 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -3332,6 +3332,7 @@ make_wireless_setting (shvarFile *ifcfg, char *value = NULL; gint64 chan = 0; NMSettingMacRandomization mac_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER; + NMSettingWirelessPowersave powersave = NM_SETTING_WIRELESS_POWERSAVE_DEFAULT; s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); @@ -3509,9 +3510,28 @@ make_wireless_setting (shvarFile *ifcfg, svGetValueBoolean (ifcfg, "SSID_HIDDEN", FALSE), NULL); + value = svGetValueFull (ifcfg, "POWERSAVE", FALSE); + if (value) { + if (!strcmp (value, "default")) + powersave = NM_SETTING_WIRELESS_POWERSAVE_DEFAULT; + else if (!strcmp (value, "ignore")) + powersave = NM_SETTING_WIRELESS_POWERSAVE_IGNORE; + else if (!strcmp (value, "disable") || !strcmp (value, "no")) + powersave = NM_SETTING_WIRELESS_POWERSAVE_DISABLE; + else if (!strcmp (value, "enable") || !strcmp (value, "yes")) + powersave = NM_SETTING_WIRELESS_POWERSAVE_ENABLE; + else { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid POWERSAVE value '%s'", value); + g_free (value); + goto error; + } + g_free (value); + } + g_object_set (s_wireless, NM_SETTING_WIRELESS_POWERSAVE, - svGetValueBoolean (ifcfg, "POWERSAVE", FALSE) ? 1 : 0, + powersave, NULL); value = svGetValueFull (ifcfg, "MAC_ADDRESS_RANDOMIZATION", FALSE); @@ -3525,6 +3545,7 @@ make_wireless_setting (shvarFile *ifcfg, else { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid MAC_ADDRESS_RANDOMIZATION value '%s'", value); + g_free (value); goto error; } g_free (value); diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index 242af0c93..a524b7b79 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -981,7 +981,22 @@ write_wireless_setting (NMConnection *connection, } svSetValue (ifcfg, "SSID_HIDDEN", nm_setting_wireless_get_hidden (s_wireless) ? "yes" : NULL, TRUE); - svSetValue (ifcfg, "POWERSAVE", nm_setting_wireless_get_powersave (s_wireless) ? "yes" : NULL, TRUE); + + switch (nm_setting_wireless_get_powersave (s_wireless)) { + case NM_SETTING_WIRELESS_POWERSAVE_IGNORE: + svSetValue (ifcfg, "POWERSAVE", "ignore", TRUE); + break; + case NM_SETTING_WIRELESS_POWERSAVE_DISABLE: + svSetValue (ifcfg, "POWERSAVE", "disable", TRUE); + break; + case NM_SETTING_WIRELESS_POWERSAVE_ENABLE: + svSetValue (ifcfg, "POWERSAVE", "enable", TRUE); + break; + default: + case NM_SETTING_WIRELESS_POWERSAVE_DEFAULT: + svSetValue (ifcfg, "POWERSAVE", NULL, TRUE); + break; + } svSetValue (ifcfg, "MAC_ADDRESS_RANDOMIZATION", NULL, TRUE); switch (nm_setting_wireless_get_mac_address_randomization (s_wireless)) {