[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