diff --git a/include/NetworkManager.h b/include/NetworkManager.h
index 3d35a59405..d45ad07b3f 100644
--- a/include/NetworkManager.h
+++ b/include/NetworkManager.h
@@ -158,6 +158,7 @@ typedef enum {
* @NM_WIFI_DEVICE_CAP_WPA: device supports WPA1 authentication
* @NM_WIFI_DEVICE_CAP_RSN: device supports WPA2/RSN authentication
* @NM_WIFI_DEVICE_CAP_AP: device supports Access Point mode
+ * @NM_WIFI_DEVICE_CAP_ADHOC: device supports Ad-Hoc mode
*
* 802.11 specific device encryption and authentication capabilities.
**/
@@ -169,7 +170,8 @@ typedef enum {
NM_WIFI_DEVICE_CAP_CIPHER_CCMP = 0x00000008,
NM_WIFI_DEVICE_CAP_WPA = 0x00000010,
NM_WIFI_DEVICE_CAP_RSN = 0x00000020,
- NM_WIFI_DEVICE_CAP_AP = 0x00000040
+ NM_WIFI_DEVICE_CAP_AP = 0x00000040,
+ NM_WIFI_DEVICE_CAP_ADHOC = 0x00000080
} NMDeviceWifiCapabilities;
diff --git a/introspection/nm-device-wifi.xml b/introspection/nm-device-wifi.xml
index f8eddd7039..dcfa20ccb9 100644
--- a/introspection/nm-device-wifi.xml
+++ b/introspection/nm-device-wifi.xml
@@ -122,6 +122,9 @@
The device supports Access Point mode.
+
+ The device supports Ad-Hoc mode.
+
diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c
index 67a10d43f0..925a0bd5e1 100644
--- a/src/nm-device-wifi.c
+++ b/src/nm-device-wifi.c
@@ -1016,6 +1016,7 @@ check_connection_compatible (NMDevice *device,
NMSettingWireless *s_wireless;
const GByteArray *mac;
const GSList *mac_blacklist, *mac_blacklist_iter;
+ const char *mode;
s_con = nm_connection_get_setting_connection (connection);
g_assert (s_con);
@@ -1071,8 +1072,17 @@ check_connection_compatible (NMDevice *device,
return FALSE;
}
- /* Early exit if supplicant or device don't support AP mode */
- if (g_strcmp0 (nm_setting_wireless_get_mode (s_wireless), NM_SETTING_WIRELESS_MODE_AP) == 0) {
+ /* Early exit if supplicant or device doesn't support requested mode */
+ mode = nm_setting_wireless_get_mode (s_wireless);
+ if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0) {
+ if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_ADHOC)) {
+ g_set_error_literal (error,
+ NM_WIFI_ERROR,
+ NM_WIFI_ERROR_ADHOC_MODE_UNSUPPORTED,
+ "Ad-Hoc mode is not supported by this device.");
+ return FALSE;
+ }
+ } else if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_AP) == 0) {
if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_AP)) {
g_set_error_literal (error,
NM_WIFI_ERROR,
diff --git a/src/nm-device-wifi.h b/src/nm-device-wifi.h
index 425b852514..368d0b800c 100644
--- a/src/nm-device-wifi.h
+++ b/src/nm-device-wifi.h
@@ -48,6 +48,7 @@ typedef enum {
NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, /*< nick=AccessPointNotFound >*/
NM_WIFI_ERROR_SCAN_NOT_ALLOWED, /*< nick=ScanNotAllowed >*/
NM_WIFI_ERROR_AP_MODE_UNSUPPORTED, /*< nick=ApModeUnsupported >*/
+ NM_WIFI_ERROR_ADHOC_MODE_UNSUPPORTED, /*< nick=AdhocModeUnsupported >*/
} NMWifiError;
#define NM_DEVICE_WIFI_HW_ADDRESS "hw-address"
diff --git a/src/wifi/wifi-utils-nl80211.c b/src/wifi/wifi-utils-nl80211.c
index 5a7103ee3a..f227d21440 100644
--- a/src/wifi/wifi-utils-nl80211.c
+++ b/src/wifi/wifi-utils-nl80211.c
@@ -700,10 +700,10 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg)
int i;
nla_for_each_nested (nl_mode, tb[NL80211_ATTR_SUPPORTED_IFTYPES], i) {
- if (nla_type (nl_mode) == NL80211_IFTYPE_AP) {
+ if (nla_type (nl_mode) == NL80211_IFTYPE_AP)
info->caps |= NM_WIFI_DEVICE_CAP_AP;
- break;
- }
+ else if (nla_type (nl_mode) == NL80211_IFTYPE_ADHOC)
+ info->caps |= NM_WIFI_DEVICE_CAP_ADHOC;
}
}
diff --git a/src/wifi/wifi-utils-wext.c b/src/wifi/wifi-utils-wext.c
index 37cd94e987..6e990aed76 100644
--- a/src/wifi/wifi-utils-wext.c
+++ b/src/wifi/wifi-utils-wext.c
@@ -556,6 +556,12 @@ wext_get_caps (WifiDataWext *wext, struct iw_range *range)
caps &= ~WPA_CAPS;
}
+ /* There's no way to detect Ad-Hoc/AP mode support with WEXT
+ * (other than actually trying to do it), so just assume that
+ * Ad-Hoc is supported and AP isn't.
+ */
+ caps |= NM_WIFI_DEVICE_CAP_ADHOC;
+
return caps;
}