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@xxxxxxxxxxxx> --- 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 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap