core: add NM_WIFI_DEVICE_CAP_ADHOC

Some wireless devices don't support Ad-Hoc mode. Expose this fact in
the wireless capabilities so that clients can disable the hot-spot
option if neither CAP_ADHOC nor CAP_AP is available.

https://bugzilla.gnome.org/show_bug.cgi?id=692869
This commit is contained in:
Dan Winship 2013-01-31 10:40:38 -05:00
parent df796527a4
commit fc700e9213
6 changed files with 28 additions and 6 deletions

View file

@ -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;

View file

@ -122,6 +122,9 @@
<tp:flag suffix="AP" value="0x40">
<tp:docstring>The device supports Access Point mode.</tp:docstring>
</tp:flag>
<tp:flag suffix="ADHOC" value="0x80">
<tp:docstring>The device supports Ad-Hoc mode.</tp:docstring>
</tp:flag>
</tp:flags>
</interface>
</node>

View file

@ -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,

View file

@ -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"

View file

@ -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;
}
}

View file

@ -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;
}