supplicant: honor the 'wifi.channel-width' property in AP mode

This commit is contained in:
Beniamino Galvani
2024-05-24 15:23:42 +02:00
committed by Fernando Fernandez Mancera
parent a591c0ca95
commit 7bb5961779
2 changed files with 87 additions and 0 deletions

View File

@@ -499,6 +499,52 @@ nm_supplicant_config_add_setting_macsec(NMSupplicantConfig *self,
return TRUE;
}
static void
get_ap_params(guint freq,
NMSettingWirelessChannelWidth width,
guint *out_ht40,
int *out_max_oper_chwidth,
guint *out_center_freq)
{
*out_ht40 = 0;
*out_max_oper_chwidth = -1;
*out_center_freq = 0;
switch (width) {
case NM_SETTING_WIRELESS_CHANNEL_WIDTH_40MHZ:
*out_ht40 = 1;
*out_max_oper_chwidth = 0;
return;
case NM_SETTING_WIRELESS_CHANNEL_WIDTH_80MHZ:
{
guint channel;
if (freq < 5000) {
/* the setting is not valid */
nm_assert_not_reached();
return;
}
/* Determine the center channel according to the table at
* https://en.wikipedia.org/wiki/List_of_WLAN_channels */
channel = (freq - 5000) / 5;
channel = ((channel / 4 - 1) / 4) * 16 + 10;
*out_ht40 = 1;
*out_max_oper_chwidth = 1;
*out_center_freq = 5000 + 5 * channel;
return;
}
case NM_SETTING_WIRELESS_CHANNEL_WIDTH_AUTO:
case NM_SETTING_WIRELESS_CHANNEL_WIDTH_20MHZ:
default:
/* in case of unknown enum value, fall back to the safest parameters */
return;
}
}
gboolean
nm_supplicant_config_add_setting_wireless(NMSupplicantConfig *self,
NMSettingWireless *setting,
@@ -562,10 +608,48 @@ nm_supplicant_config_add_setting_wireless(NMSupplicantConfig *self,
if ((is_adhoc || is_ap || is_mesh) && fixed_freq) {
gs_free char *str_freq = NULL;
guint ht40;
int max_oper_chwidth;
guint center_freq;
str_freq = g_strdup_printf("%u", fixed_freq);
if (!nm_supplicant_config_add_option(self, "frequency", str_freq, -1, NULL, error))
return FALSE;
if (is_ap) {
get_ap_params(fixed_freq,
nm_setting_wireless_get_channel_width(setting),
&ht40,
&max_oper_chwidth,
&center_freq);
if (!nm_supplicant_config_add_option(self, "ht40", ht40 ? "1" : "0", -1, NULL, error))
return FALSE;
if (center_freq != 0) {
g_free(str_freq);
str_freq = g_strdup_printf("%u", center_freq);
if (!nm_supplicant_config_add_option(self,
"vht_center_freq1",
str_freq,
-1,
NULL,
error))
return FALSE;
}
if (max_oper_chwidth >= 0) {
g_free(str_freq);
str_freq = g_strdup_printf("%u", max_oper_chwidth);
if (!nm_supplicant_config_add_option(self,
"max_oper_chwidth",
str_freq,
-1,
NULL,
error))
return FALSE;
}
}
}
/* Except for Ad-Hoc, Hotspot and Mesh, request that the driver probe for the

View File

@@ -73,6 +73,7 @@ static const struct Opt opt_table[] = {
OPT_KEYWORD("freq_list", NULL),
OPT_INT("frequency", 2412, 5825),
OPT_KEYWORD("group", NM_MAKE_STRV("CCMP", "TKIP", "WEP104", "WEP40", "GCMP-256", )),
OPT_INT("ht40", 0, 1),
OPT_BYTES("identity", 0),
OPT_INT("ieee80211w", 0, 2),
OPT_INT("ignore_broadcast_ssid", 0, 2),
@@ -99,6 +100,7 @@ static const struct Opt opt_table[] = {
OPT_INT("macsec_offload", 0, 2),
OPT_INT("macsec_policy", 0, 1),
OPT_INT("macsec_port", 1, 65534),
OPT_INT("max_oper_chwidth", 0, 9),
OPT_BYTES("mka_cak", 65536),
OPT_BYTES("mka_ckn", 65536),
OPT_BYTES("nai", 0),
@@ -155,6 +157,7 @@ static const struct Opt opt_table[] = {
OPT_BYTES("ssid", 32),
OPT_BYTES("subject_match", 0),
OPT_BYTES("subject_match2", 0),
OPT_INT("vht_center_freq1", 0, 100000),
OPT_BYTES("wep_key0", 0),
OPT_BYTES("wep_key1", 0),
OPT_BYTES("wep_key2", 0),