diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index 0f4b12ec0..aee29467c 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -1007,7 +1007,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, /* TODO: check this. hostapd_get_hw_features() initializes * too much stuff. */ /* hostapd_get_hw_features(hapd->iface); */ - hostapd_channel_list_updated(hapd->iface); + hostapd_channel_list_updated( + hapd->iface, data->channel_list_changed.initiator); break; #endif /* NEED_AP_MLME */ default: diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 60224ccbf..a06ec9f34 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -961,9 +961,9 @@ static void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx) } -void hostapd_channel_list_updated(struct hostapd_iface *iface) +void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator) { - if (!iface->wait_channel_update) + if (!iface->wait_channel_update || initiator != REGDOM_SET_BY_USER) return; wpa_printf(MSG_DEBUG, "Channel list updated - continue setup"); diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 1887531f9..9a10626b4 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -375,7 +375,7 @@ int hostapd_reload_iface(struct hostapd_iface *hapd_iface); int hostapd_disable_iface(struct hostapd_iface *hapd_iface); int hostapd_add_iface(struct hapd_interfaces *ifaces, char *buf); int hostapd_remove_iface(struct hapd_interfaces *ifaces, char *buf); -void hostapd_channel_list_updated(struct hostapd_iface *iface); +void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator); void hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s); const char * hostapd_state_text(enum hostapd_iface_state s); diff --git a/src/drivers/driver.h b/src/drivers/driver.h index f233032eb..c56af83bc 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -42,6 +42,13 @@ #define HOSTAPD_CHAN_VHT_50_30 0x00002000 #define HOSTAPD_CHAN_VHT_70_10 0x00004000 +enum reg_change_initiator { + REGDOM_SET_BY_CORE, + REGDOM_SET_BY_USER, + REGDOM_SET_BY_DRIVER, + REGDOM_SET_BY_COUNTRY_IE, +}; + /** * struct hostapd_channel_data - Channel information */ @@ -3999,6 +4006,14 @@ union wpa_event_data { unsigned int freq_filter; struct dl_list survey_list; /* struct freq_survey */ } survey_results; + + /** + * channel_list_changed - Data for EVENT_CHANNEL_LIST_CHANGED + * @initiator: Initiator of the regulatory change + */ + struct channel_list_changed { + enum reg_change_initiator initiator; + } channel_list_changed; }; /** diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 90d04e48d..48ac6a210 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -2614,6 +2614,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, struct nlattr **tb) { struct wpa_driver_nl80211_data *drv = bss->drv; + union wpa_event_data data; wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s", cmd, nl80211_command_to_string(cmd), bss->ifname); @@ -2713,8 +2714,33 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, break; case NL80211_CMD_REG_CHANGE: wpa_printf(MSG_DEBUG, "nl80211: Regulatory domain change"); + if (tb[NL80211_ATTR_REG_INITIATOR] == NULL) + break; + os_memset(&data, 0, sizeof(data)); + switch (nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR])) { + case NL80211_REGDOM_SET_BY_CORE: + data.channel_list_changed.initiator = + REGDOM_SET_BY_CORE; + break; + case NL80211_REGDOM_SET_BY_USER: + data.channel_list_changed.initiator = + REGDOM_SET_BY_USER; + break; + case NL80211_REGDOM_SET_BY_DRIVER: + data.channel_list_changed.initiator = + REGDOM_SET_BY_DRIVER; + break; + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + data.channel_list_changed.initiator = + REGDOM_SET_BY_COUNTRY_IE; + break; + default: + wpa_printf(MSG_DEBUG, "nl80211: Unknown reg change initiator %d received", + nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR])); + break; + } wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED, - NULL); + &data); break; case NL80211_CMD_REG_BEACON_HINT: wpa_printf(MSG_DEBUG, "nl80211: Regulatory beacon hint");