[PATCH 12/15] wpa_supplicant: Extend verify_channel() and make it global

Andrei Otcheretianski andrei.otcheretianski at intel.com
Wed Dec 28 05:06:44 PST 2016


From: Avraham Stern <avraham.stern at intel.com>

Extend verify_channel() to return whether IR is allowed on the
channel or not, and make it a global function so it can be used
in other files too.

This makes this function useful for checking not only if a channel
is supported but also if it is allowed for active and passive scan.

Signed-off-by: Avraham Stern <avraham.stern at intel.com>
---
 src/common/hw_features_common.c | 191 +++++++++++++++++++++++++++++++++++++
 src/common/hw_features_common.h |   7 ++
 wpa_supplicant/op_classes.c     | 203 +++-------------------------------------
 wpa_supplicant/p2p_supplicant.c |   5 +-
 4 files changed, 213 insertions(+), 193 deletions(-)

diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c
index 9c37ea6..1425754 100644
--- a/src/common/hw_features_common.c
+++ b/src/common/hw_features_common.c
@@ -453,3 +453,194 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
 
 	return 0;
 }
+
+
+static enum chan_allowed allow_channel(struct hostapd_hw_modes *mode, u8 chan,
+				       unsigned int *flags)
+{
+	int i;
+
+	for (i = 0; i < mode->num_channels; i++) {
+		if (mode->channels[i].chan == chan)
+			break;
+	}
+
+	if (i == mode->num_channels ||
+	    (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED))
+		return NOT_ALLOWED;
+
+	if (flags)
+		*flags = mode->channels[i].flag;
+
+	if (mode->channels[i].flag & HOSTAPD_CHAN_NO_IR)
+		return NO_IR;
+
+	return ALLOWED;
+}
+
+
+static int get_center_80mhz(struct hostapd_hw_modes *mode, u8 channel)
+{
+	u8 center_channels[] = { 42, 58, 106, 122, 138, 155 };
+	size_t i;
+
+	if (mode->mode != HOSTAPD_MODE_IEEE80211A)
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(center_channels); i++) {
+		/*
+		 * In 80 MHz, the bandwidth "spans" 12 channels (e.g., 36-48),
+		 * so the center channel is 6 channels away from the start/end.
+		 */
+		if (channel >= center_channels[i] - 6 &&
+		    channel <= center_channels[i] + 6)
+			return center_channels[i];
+	}
+
+	return 0;
+}
+
+
+static enum chan_allowed verify_80mhz(struct hostapd_hw_modes *mode, u8 channel)
+{
+	u8 center_chan;
+	unsigned int i;
+	unsigned int no_ir = 0;
+
+	center_chan = get_center_80mhz(mode, channel);
+	if (!center_chan)
+		return NOT_ALLOWED;
+
+	/* check all the channels are available */
+	for (i = 0; i < 4; i++) {
+		unsigned int flags;
+		u8 adj_chan = center_chan - 6 + i * 4;
+
+		if (allow_channel(mode, adj_chan, &flags) == NOT_ALLOWED)
+			return NOT_ALLOWED;
+
+		if ((i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_70)) ||
+		    (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_50)) ||
+		    (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_30)) ||
+		    (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_10)))
+			return NOT_ALLOWED;
+
+		if (flags & HOSTAPD_CHAN_NO_IR)
+			no_ir = 1;
+	}
+
+	if (no_ir)
+		return NO_IR;
+
+	return ALLOWED;
+}
+
+
+static int get_center_160mhz(struct hostapd_hw_modes *mode, u8 channel)
+{
+	u8 center_channels[] = { 50, 114 };
+	unsigned int i;
+
+	if (mode->mode != HOSTAPD_MODE_IEEE80211A)
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(center_channels); i++) {
+		/*
+		 * In 160 MHz, the bandwidth "spans" 28 channels (e.g., 36-64),
+		 * so the center channel is 14 channels away from the start/end.
+		 */
+		if (channel >= center_channels[i] - 14 &&
+		    channel <= center_channels[i] + 14)
+			return center_channels[i];
+	}
+
+	return 0;
+}
+
+
+static enum chan_allowed verify_160mhz(struct hostapd_hw_modes *mode,
+				       u8 channel)
+{
+	u8 center_chan;
+	unsigned int i;
+	unsigned int no_ir = 0;
+
+	center_chan = get_center_160mhz(mode, channel);
+	if (!center_chan)
+		return NOT_ALLOWED;
+
+	/* Check all the channels are available */
+	for (i = 0; i < 8; i++) {
+		unsigned int flags;
+		u8 adj_chan = center_chan - 14 + i * 4;
+
+		if (allow_channel(mode, adj_chan, &flags) == NOT_ALLOWED)
+			return NOT_ALLOWED;
+
+		if ((i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_150)) ||
+		    (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_130)) ||
+		    (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_110)) ||
+		    (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_90)) ||
+		    (i == 4 && !(flags & HOSTAPD_CHAN_VHT_90_70)) ||
+		    (i == 5 && !(flags & HOSTAPD_CHAN_VHT_110_50)) ||
+		    (i == 6 && !(flags & HOSTAPD_CHAN_VHT_130_30)) ||
+		    (i == 7 && !(flags & HOSTAPD_CHAN_VHT_150_10)))
+			return NOT_ALLOWED;
+
+		if (flags & HOSTAPD_CHAN_NO_IR)
+			no_ir = 1;
+	}
+
+	if (no_ir)
+		return NO_IR;
+
+	return ALLOWED;
+}
+
+
+enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 channel,
+				 u8 bw)
+{
+	unsigned int flag = 0;
+	enum chan_allowed res, res2;
+
+	res2 = res = allow_channel(mode, channel, &flag);
+	if (bw == BW40MINUS) {
+		if (!(flag & HOSTAPD_CHAN_HT40MINUS))
+			return NOT_ALLOWED;
+		res2 = allow_channel(mode, channel - 4, NULL);
+	} else if (bw == BW40PLUS) {
+		if (!(flag & HOSTAPD_CHAN_HT40PLUS))
+			return NOT_ALLOWED;
+		res2 = allow_channel(mode, channel + 4, NULL);
+	} else if (bw == BW80) {
+		/*
+		 * channel is a center channel and as such, not necessarily a
+		 * valid 20 MHz channels. Override earlier allow_channel()
+		 * result and use only the 80 MHz specific version.
+		 */
+		res2 = res = verify_80mhz(mode, channel);
+	} else if (bw == BW160) {
+		/*
+		 * channel is a center channel and as such, not necessarily a
+		 * valid 20 MHz channels. Override earlier allow_channel()
+		 * result and use only the 160 MHz specific version.
+		 */
+		res2 = res = verify_160mhz(mode, channel);
+	} else if (bw == BW80P80) {
+		/*
+		 * channel is a center channel and as such, not necessarily a
+		 * valid 20 MHz channels. Override earlier allow_channel()
+		 * result and use only the 80 MHz specific version.
+		 */
+		res2 = res = verify_80mhz(mode, channel);
+	}
+
+	if (res == NOT_ALLOWED || res2 == NOT_ALLOWED)
+		return NOT_ALLOWED;
+
+	if (res == NO_IR || res2 == NO_IR)
+		return NO_IR;
+
+	return ALLOWED;
+}
diff --git a/src/common/hw_features_common.h b/src/common/hw_features_common.h
index 7360b4e..99b710e 100644
--- a/src/common/hw_features_common.h
+++ b/src/common/hw_features_common.h
@@ -36,4 +36,11 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
 			    int vht_oper_chwidth, int center_segment0,
 			    int center_segment1, u32 vht_caps);
 
+enum chan_allowed {
+	NOT_ALLOWED, NO_IR, ALLOWED
+};
+
+enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 channel,
+				 u8 bw);
+
 #endif /* HW_FEATURES_COMMON_H */
diff --git a/wpa_supplicant/op_classes.c b/wpa_supplicant/op_classes.c
index c463de3..b6b85c1 100644
--- a/wpa_supplicant/op_classes.c
+++ b/wpa_supplicant/op_classes.c
@@ -14,182 +14,7 @@
 #include "utils/common.h"
 #include "common/ieee802_11_common.h"
 #include "wpa_supplicant_i.h"
-
-
-enum chan_allowed {
-	NOT_ALLOWED, ALLOWED
-};
-
-static enum chan_allowed allow_channel(struct hostapd_hw_modes *mode, u8 chan,
-				       unsigned int *flags)
-{
-	int i;
-
-	for (i = 0; i < mode->num_channels; i++) {
-		if (mode->channels[i].chan == chan)
-			break;
-	}
-
-	if (i == mode->num_channels ||
-	    (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED))
-		return NOT_ALLOWED;
-
-	if (flags)
-		*flags = mode->channels[i].flag;
-
-	return ALLOWED;
-}
-
-
-static int get_center_80mhz(struct hostapd_hw_modes *mode, u8 channel)
-{
-	u8 center_channels[] = { 42, 58, 106, 122, 138, 155 };
-	size_t i;
-
-	if (mode->mode != HOSTAPD_MODE_IEEE80211A)
-		return 0;
-
-	for (i = 0; i < ARRAY_SIZE(center_channels); i++) {
-		/*
-		 * In 80 MHz, the bandwidth "spans" 12 channels (e.g., 36-48),
-		 * so the center channel is 6 channels away from the start/end.
-		 */
-		if (channel >= center_channels[i] - 6 &&
-		    channel <= center_channels[i] + 6)
-			return center_channels[i];
-	}
-
-	return 0;
-}
-
-
-static enum chan_allowed verify_80mhz(struct hostapd_hw_modes *mode, u8 channel)
-{
-	u8 center_chan;
-	unsigned int i;
-
-	center_chan = get_center_80mhz(mode, channel);
-	if (!center_chan)
-		return NOT_ALLOWED;
-
-	/* check all the channels are available */
-	for (i = 0; i < 4; i++) {
-		unsigned int flags;
-		u8 adj_chan = center_chan - 6 + i * 4;
-
-		if (allow_channel(mode, adj_chan, &flags) == NOT_ALLOWED)
-			return NOT_ALLOWED;
-
-		if ((i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_70)) ||
-		    (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_50)) ||
-		    (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_30)) ||
-		    (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_10)))
-			return NOT_ALLOWED;
-	}
-
-	return ALLOWED;
-}
-
-
-static int get_center_160mhz(struct hostapd_hw_modes *mode, u8 channel)
-{
-	u8 center_channels[] = { 50, 114 };
-	unsigned int i;
-
-	if (mode->mode != HOSTAPD_MODE_IEEE80211A)
-		return 0;
-
-	for (i = 0; i < ARRAY_SIZE(center_channels); i++) {
-		/*
-		 * In 160 MHz, the bandwidth "spans" 28 channels (e.g., 36-64),
-		 * so the center channel is 14 channels away from the start/end.
-		 */
-		if (channel >= center_channels[i] - 14 &&
-		    channel <= center_channels[i] + 14)
-			return center_channels[i];
-	}
-
-	return 0;
-}
-
-
-static enum chan_allowed verify_160mhz(struct hostapd_hw_modes *mode,
-				       u8 channel)
-{
-	u8 center_chan;
-	unsigned int i;
-
-	center_chan = get_center_160mhz(mode, channel);
-	if (!center_chan)
-		return NOT_ALLOWED;
-
-	/* Check all the channels are available */
-	for (i = 0; i < 8; i++) {
-		unsigned int flags;
-		u8 adj_chan = center_chan - 14 + i * 4;
-
-		if (allow_channel(mode, adj_chan, &flags) == NOT_ALLOWED)
-			return NOT_ALLOWED;
-
-		if ((i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_150)) ||
-		    (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_130)) ||
-		    (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_110)) ||
-		    (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_90)) ||
-		    (i == 4 && !(flags & HOSTAPD_CHAN_VHT_90_70)) ||
-		    (i == 5 && !(flags & HOSTAPD_CHAN_VHT_110_50)) ||
-		    (i == 6 && !(flags & HOSTAPD_CHAN_VHT_130_30)) ||
-		    (i == 7 && !(flags & HOSTAPD_CHAN_VHT_150_10)))
-			return NOT_ALLOWED;
-	}
-
-	return ALLOWED;
-}
-
-
-static enum chan_allowed verify_channel(struct hostapd_hw_modes *mode,
-					u8 channel, u8 bw)
-{
-	unsigned int flag = 0;
-	enum chan_allowed res, res2;
-
-	res2 = res = allow_channel(mode, channel, &flag);
-	if (bw == BW40MINUS) {
-		if (!(flag & HOSTAPD_CHAN_HT40MINUS))
-			return NOT_ALLOWED;
-		res2 = allow_channel(mode, channel - 4, NULL);
-	} else if (bw == BW40PLUS) {
-		if (!(flag & HOSTAPD_CHAN_HT40PLUS))
-			return NOT_ALLOWED;
-		res2 = allow_channel(mode, channel + 4, NULL);
-	} else if (bw == BW80) {
-		/*
-		 * channel is a center channel and as such, not necessarily a
-		 * valid 20 MHz channels. Override earlier allow_channel()
-		 * result and use only the 80 MHz specific version.
-		 */
-		res2 = res = verify_80mhz(mode, channel);
-	} else if (bw == BW160) {
-		/*
-		 * channel is a center channel and as such, not necessarily a
-		 * valid 20 MHz channels. Override earlier allow_channel()
-		 * result and use only the 160 MHz specific version.
-		 */
-		res2 = res = verify_160mhz(mode, channel);
-	} else if (bw == BW80P80) {
-		/*
-		 * channel is a center channel and as such, not necessarily a
-		 * valid 20 MHz channels. Override earlier allow_channel()
-		 * result and use only the 80 MHz specific version.
-		 */
-		res2 = res = verify_80mhz(mode, channel);
-	}
-
-	if (res == NOT_ALLOWED || res2 == NOT_ALLOWED)
-		return NOT_ALLOWED;
-
-	return ALLOWED;
-}
-
+#include "common/hw_features_common.h"
 
 static int wpas_op_class_supported(struct wpa_supplicant *wpa_s,
 				   const struct oper_class_map *op_class)
@@ -207,8 +32,8 @@ static int wpas_op_class_supported(struct wpa_supplicant *wpa_s,
 		u8 channels[] = { 42, 58, 106, 122, 138, 155 };
 
 		for (i = 0; i < ARRAY_SIZE(channels); i++) {
-			if (verify_channel(mode, channels[i], op_class->bw) ==
-			    ALLOWED)
+			if (verify_channel(mode, channels[i], op_class->bw) !=
+			    NOT_ALLOWED)
 				return 1;
 		}
 
@@ -217,25 +42,25 @@ static int wpas_op_class_supported(struct wpa_supplicant *wpa_s,
 
 	if (op_class->op_class == 129) {
 		/* Check if either 160 MHz channels is allowed */
-		return verify_channel(mode, 50, op_class->bw) == ALLOWED ||
-			verify_channel(mode, 114, op_class->bw) == ALLOWED;
+		return verify_channel(mode, 50, op_class->bw) != NOT_ALLOWED ||
+			verify_channel(mode, 114, op_class->bw) != NOT_ALLOWED;
 	}
 
 	if (op_class->op_class == 130) {
 		/* Need at least two non-contiguous 80 MHz segments */
 		found = 0;
 
-		if (verify_channel(mode, 42, op_class->bw) == ALLOWED ||
-		    verify_channel(mode, 58, op_class->bw) == ALLOWED)
+		if (verify_channel(mode, 42, op_class->bw) != NOT_ALLOWED ||
+		    verify_channel(mode, 58, op_class->bw) != NOT_ALLOWED)
 			found++;
-		if (verify_channel(mode, 106, op_class->bw) == ALLOWED ||
-		    verify_channel(mode, 122, op_class->bw) == ALLOWED ||
-		    verify_channel(mode, 138, op_class->bw) == ALLOWED)
+		if (verify_channel(mode, 106, op_class->bw) != NOT_ALLOWED ||
+		    verify_channel(mode, 122, op_class->bw) != NOT_ALLOWED ||
+		    verify_channel(mode, 138, op_class->bw) != NOT_ALLOWED)
 			found++;
-		if (verify_channel(mode, 106, op_class->bw) == ALLOWED &&
-		    verify_channel(mode, 138, op_class->bw) == ALLOWED)
+		if (verify_channel(mode, 106, op_class->bw) != NOT_ALLOWED &&
+		    verify_channel(mode, 138, op_class->bw) != NOT_ALLOWED)
 			found++;
-		if (verify_channel(mode, 155, op_class->bw) == ALLOWED)
+		if (verify_channel(mode, 155, op_class->bw) != NOT_ALLOWED)
 			found++;
 
 		if (found >= 2)
@@ -247,7 +72,7 @@ static int wpas_op_class_supported(struct wpa_supplicant *wpa_s,
 	found = 0;
 	for (chan = op_class->min_chan; chan <= op_class->max_chan;
 	     chan += op_class->inc) {
-		if (verify_channel(mode, chan, op_class->bw) == ALLOWED) {
+		if (verify_channel(mode, chan, op_class->bw) != NOT_ALLOWED) {
 			found = 1;
 			break;
 		}
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 6dc08fa..22b937b 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -37,6 +37,7 @@
 #include "wps_supplicant.h"
 #include "p2p_supplicant.h"
 #include "wifi_display.h"
+#include "common/hw_features_common.h"
 
 
 /*
@@ -3334,10 +3335,6 @@ static int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s,
 }
 
 
-enum chan_allowed {
-	NOT_ALLOWED, NO_IR, ALLOWED
-};
-
 static int has_channel(struct wpa_global *global,
 		       struct hostapd_hw_modes *mode, u8 chan, int *flags)
 {
-- 
1.9.1




More information about the Hostap mailing list