#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 "
* @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 {
+ unsigned int freq;
+ unsigned int max_tx_power;
+ bool disabled;
+ bool no_ir;
+ bool radar;
+ } beacon_hint_before, beacon_hint_after;
} channel_list_changed;
/**
}
-static void nl80211_dump_freq(const char *title, struct nlattr *nl_freq)
+static void nl80211_parse_freq_attrs(const char *title, 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 },
tb[NL80211_FREQUENCY_ATTR_DISABLED] ? " disabled" : "",
tb[NL80211_FREQUENCY_ATTR_NO_IR] ? " no-IR" : "",
tb[NL80211_FREQUENCY_ATTR_RADAR] ? " radar" : "");
+
+ attrs->freq = freq;
+ attrs->max_tx_power = max_tx_power;
+ if (tb[NL80211_FREQUENCY_ATTR_DISABLED])
+ attrs->disabled = true;
+ if (tb[NL80211_FREQUENCY_ATTR_NO_IR])
+ attrs->no_ir = true;
+ if (tb[NL80211_FREQUENCY_ATTR_RADAR])
+ attrs->radar = true;
}
data.channel_list_changed.initiator = REGDOM_BEACON_HINT;
if (tb[NL80211_ATTR_FREQ_BEFORE])
- nl80211_dump_freq("before", tb[NL80211_ATTR_FREQ_BEFORE]);
+ nl80211_parse_freq_attrs(
+ "before", 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(
+ "after", tb[NL80211_ATTR_FREQ_AFTER],
+ &data.channel_list_changed.beacon_hint_after);
wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED, &data);
}
}
+static void wpas_beacon_hint(struct wpa_supplicant *wpa_s, const char *title,
+ struct frequency_attrs *attrs)
+{
+ if (!attrs->freq)
+ return;
+ wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REGDOM_BEACON_HINT
+ "%s freq=%u max_tx_power=%u%s%s%s",
+ title, attrs->freq, attrs->max_tx_power,
+ attrs->disabled ? " disabled=1" : "",
+ attrs->no_ir ? " no_ir=1" : "",
+ attrs->radar ? " radar=1" : "");
+}
+
+
void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s,
struct channel_list_changed *info)
{
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) {
+ wpas_beacon_hint(ifs, "before",
+ &info->beacon_hint_before);
+ wpas_beacon_hint(ifs, "after",
+ &info->beacon_hint_after);
+ }
}
if (wpa_s->drv_priv == NULL)