diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index 32bd98bb1e..c7ab7f0460 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -1123,6 +1123,7 @@ nm_wifi_ap_complete_connection (NMWifiAP *self, return nm_wifi_utils_complete_connection (priv->ssid, priv->address, priv->mode, + priv->freq, priv->flags, priv->wpa_flags, priv->rsn_flags, diff --git a/src/devices/wifi/nm-wifi-utils.c b/src/devices/wifi/nm-wifi-utils.c index 4845201a2f..426eeea83b 100644 --- a/src/devices/wifi/nm-wifi-utils.c +++ b/src/devices/wifi/nm-wifi-utils.c @@ -24,6 +24,7 @@ #include #include "nm-utils.h" +#include "nm-core-internal.h" static gboolean verify_no_wep (NMSettingWirelessSecurity *s_wsec, const char *tag, GError **error) @@ -526,6 +527,7 @@ gboolean nm_wifi_utils_complete_connection (GBytes *ap_ssid, const char *bssid, NM80211Mode ap_mode, + guint32 ap_freq, guint32 ap_flags, guint32 ap_wpa_flags, guint32 ap_rsn_flags, @@ -539,6 +541,7 @@ nm_wifi_utils_complete_connection (GBytes *ap_ssid, GBytes *ssid; const char *mode, *key_mgmt, *auth_alg, *leap_username; gboolean adhoc = FALSE; + gboolean mesh = FALSE; s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); @@ -575,6 +578,10 @@ nm_wifi_utils_complete_connection (GBytes *ap_ssid, if (ap_mode == NM_802_11_MODE_ADHOC) valid = TRUE; adhoc = TRUE; + } else if (!strcmp (mode, NM_SETTING_WIRELESS_MODE_MESH)) { + if (ap_mode == NM_802_11_MODE_MESH) + valid = TRUE; + mesh = TRUE; } if (valid == FALSE) { @@ -590,10 +597,57 @@ nm_wifi_utils_complete_connection (GBytes *ap_ssid, if (ap_mode == NM_802_11_MODE_ADHOC) { mode = NM_SETTING_WIRELESS_MODE_ADHOC; adhoc = TRUE; + } else if (ap_mode == NM_802_11_MODE_MESH) { + mode = NM_SETTING_WIRELESS_MODE_MESH; + mesh = TRUE; } g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MODE, mode, NULL); } + /* For now mesh requires channel and band, fill them only if both not present. + * Do not check existing values against an existing ap/mesh point, + * mesh join will start a new network if required */ + if (mesh) { + const char *band; + guint32 channel; + gboolean band_valid = TRUE; + gboolean chan_valid = TRUE; + gboolean valid; + + band = nm_setting_wireless_get_band (s_wifi); + channel = nm_setting_wireless_get_channel (s_wifi); + + valid = ((band == NULL) && (channel == 0)) + || ((band != NULL) && (channel != 0)); + + if ((band == NULL) && (channel == 0)) { + channel = nm_utils_wifi_freq_to_channel (ap_freq); + if (channel) { + g_object_set (s_wifi, + NM_SETTING_WIRELESS_CHANNEL, channel, + NULL); + } else { + chan_valid = FALSE; + } + + band = nm_utils_wifi_freq_to_band (ap_freq); + if (band) { + g_object_set (s_wifi, NM_SETTING_WIRELESS_BAND, band, NULL); + } else { + band_valid = FALSE; + } + } + + if (!valid || !chan_valid || !band_valid) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match mesh point")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MODE); + return FALSE; + } + } + /* Security */ /* Open */ diff --git a/src/devices/wifi/nm-wifi-utils.h b/src/devices/wifi/nm-wifi-utils.h index ccae69b13a..251d122fcc 100644 --- a/src/devices/wifi/nm-wifi-utils.h +++ b/src/devices/wifi/nm-wifi-utils.h @@ -36,6 +36,7 @@ typedef enum { gboolean nm_wifi_utils_complete_connection (GBytes *ssid, const char *bssid, NM80211Mode mode, + guint32 ap_freq, guint32 flags, guint32 wpa_flags, guint32 rsn_flags, diff --git a/src/devices/wifi/tests/test-devices-wifi.c b/src/devices/wifi/tests/test-devices-wifi.c index a81ebda080..a0b3e17fff 100644 --- a/src/devices/wifi/tests/test-devices-wifi.c +++ b/src/devices/wifi/tests/test-devices-wifi.c @@ -85,6 +85,7 @@ complete_connection (const char *ssid, return nm_wifi_utils_complete_connection (ssid_b, bssid, mode, + 0, flags, wpa_flags, rsn_flags,