[PATCH] Populate the new beacon hint event to wpa msg

Jun Yu junyuu at chromium.org
Tue Nov 28 22:54:49 PST 2023


Beacon hinting is a WiFi feature that can temporarily change the
regulatory rule flags on the channel where the radio hears the beacon.
Add a new event CTRL-EVENT-REGDOM-BEACON-HINT to notify the wpa user
about important update to the regulatory rules including which
frequencies are impacted, new power limit and new rule flags.

Signed-off-by: Jun Yu <junyuu at chromium.org>
---
 src/common/wpa_ctrl.h              |  2 ++
 src/drivers/driver.h               | 11 ++++++++
 src/drivers/driver_nl80211_event.c | 43 ++++++++++++++++++++++++++++--
 wpa_supplicant/events.c            | 17 ++++++++++++
 4 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index 416e0d6a8..154bac8fe 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -87,6 +87,8 @@ extern "C" {
 #define WPA_EVENT_BEACON_LOSS "CTRL-EVENT-BEACON-LOSS "
 /** Regulatory domain channel */
 #define WPA_EVENT_REGDOM_CHANGE "CTRL-EVENT-REGDOM-CHANGE "
+/** Regulatory beacon hint */
+#define WPA_EVENT_REGDOM_BEACON_HINT "CTRL-EVENT-REGDOM-BEACON-HINT "
 /** Channel switch started (followed by freq=<MHz> and other channel parameters)
  */
 #define WPA_EVENT_CHANNEL_SWITCH_STARTED "CTRL-EVENT-STARTED-CHANNEL-SWITCH "
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 9e4df1d78..1f3938579 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -6554,11 +6554,22 @@ union wpa_event_data {
 	 * @initiator: Initiator of the regulatory change
 	 * @type: Regulatory change type
 	 * @alpha2: Country code (or "" if not available)
+	 * @beacon_hint_before: Data for frequency attributes before beacon hint
+	 *	event if initiator == REGDOM_BEACON_HINT
+	 * @beacon_hint_after: Data for frequency attributes after beacon hint
+	 *	event if initiator == REGDOM_BEACON_HINT
 	 */
 	struct channel_list_changed {
 		enum reg_change_initiator initiator;
 		enum reg_type type;
 		char alpha2[3];
+		struct frequency_attrs {
+			u32 freq;
+			u32 max_tx_power;
+			u32 disabled : 1;
+			u32 no_ir : 1;
+			u32 radar : 1;
+		} beacon_hint_before, beacon_hint_after;
 	} channel_list_changed;
 
 	/**
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
index 60b4fb51f..5b803d1e2 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -3443,6 +3443,39 @@ static void nl80211_dump_freq(const char *title, struct nlattr *nl_freq)
 }
 
 
+static void nl80211_parse_freq_attrs(struct nlattr *nl_freq,
+				     struct frequency_attrs *attrs)
+{
+	static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
+		[NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
+		[NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
+		[NL80211_FREQUENCY_ATTR_NO_IR] = { .type = NLA_FLAG },
+		[NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
+		[NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
+	};
+	struct nlattr *tb[NL80211_FREQUENCY_ATTR_MAX + 1];
+	u32 freq = 0, max_tx_power = 0;
+
+	nla_parse(tb, NL80211_FREQUENCY_ATTR_MAX,
+		  nla_data(nl_freq), nla_len(nl_freq), freq_policy);
+
+	if (tb[NL80211_FREQUENCY_ATTR_FREQ])
+		freq = nla_get_u32(tb[NL80211_FREQUENCY_ATTR_FREQ]);
+	if (tb[NL80211_FREQUENCY_ATTR_MAX_TX_POWER])
+		max_tx_power =
+			nla_get_u32(tb[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]);
+
+	attrs->freq = freq;
+	attrs->max_tx_power = max_tx_power;
+	if (tb[NL80211_FREQUENCY_ATTR_DISABLED])
+		attrs->disabled = 1;
+	if (tb[NL80211_FREQUENCY_ATTR_NO_IR])
+		attrs->no_ir = 1;
+	if (tb[NL80211_FREQUENCY_ATTR_RADAR])
+		attrs->radar = 1;
+}
+
+
 static void nl80211_reg_beacon_hint_event(struct wpa_driver_nl80211_data *drv,
 					   struct nlattr *tb[])
 {
@@ -3452,10 +3485,16 @@ static void nl80211_reg_beacon_hint_event(struct wpa_driver_nl80211_data *drv,
 	os_memset(&data, 0, sizeof(data));
 	data.channel_list_changed.initiator = REGDOM_BEACON_HINT;
 
-	if (tb[NL80211_ATTR_FREQ_BEFORE])
+	if (tb[NL80211_ATTR_FREQ_BEFORE]) {
 		nl80211_dump_freq("before", tb[NL80211_ATTR_FREQ_BEFORE]);
-	if (tb[NL80211_ATTR_FREQ_AFTER])
+		nl80211_parse_freq_attrs(tb[NL80211_ATTR_FREQ_BEFORE],
+			&data.channel_list_changed.beacon_hint_before);
+	}
+	if (tb[NL80211_ATTR_FREQ_AFTER]) {
 		nl80211_dump_freq("after", tb[NL80211_ATTR_FREQ_AFTER]);
+		nl80211_parse_freq_attrs(tb[NL80211_ATTR_FREQ_AFTER],
+			&data.channel_list_changed.beacon_hint_after);
+	}
 
 	wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED, &data);
 }
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index da73faaaf..c04e70eb6 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -5138,6 +5138,23 @@ void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s,
 			reg_init_str(info->initiator), reg_type_str(info->type),
 			info->alpha2[0] ? " alpha2=" : "",
 			info->alpha2[0] ? info->alpha2 : "");
+
+		if (info->initiator == REGDOM_BEACON_HINT) {
+			if (info->beacon_hint_before.freq)
+				wpa_msg(ifs, MSG_INFO,
+					WPA_EVENT_REGDOM_BEACON_HINT "before freq=%u max_tx_power=%u%s%s%s",
+					info->beacon_hint_before.freq, info->beacon_hint_before.max_tx_power,
+					info->beacon_hint_before.disabled ? " disabled=1" : "",
+					info->beacon_hint_before.no_ir ? " no_ir=1" : "",
+					info->beacon_hint_before.radar ? " radar=1" : "");
+			if (info->beacon_hint_after.freq)
+				wpa_msg(ifs, MSG_INFO,
+					WPA_EVENT_REGDOM_BEACON_HINT "after freq=%u max_tx_power=%u%s%s%s",
+					info->beacon_hint_after.freq, info->beacon_hint_after.max_tx_power,
+					info->beacon_hint_after.disabled ? " disabled=1" : "",
+					info->beacon_hint_after.no_ir ? " no_ir=1" : "",
+					info->beacon_hint_after.radar ? " radar=1" : "");
+		}
 	}
 
 	if (wpa_s->drv_priv == NULL)
-- 
2.43.0.rc2.451.g8631bc7472-goog




More information about the Hostap mailing list