diff options
| author | Abhishek Singh <absingh@qti.qualcomm.com> | 2013-11-13 17:30:27 +0530 |
|---|---|---|
| committer | Sandeep Puligilla <spuligil@codeaurora.org> | 2013-11-20 14:24:40 +0530 |
| commit | b498eb4eb44bd696cbe520c516881f9feb7ecdce (patch) | |
| tree | 51dd5d67a21f09c364f1880115097e523261c245 | |
| parent | 95a686f32a99fb3db9726c03c3e692dc840db363 (diff) | |
| download | android_external_wpa_supplicant_8-b498eb4eb44bd696cbe520c516881f9feb7ecdce.tar.gz android_external_wpa_supplicant_8-b498eb4eb44bd696cbe520c516881f9feb7ecdce.tar.bz2 android_external_wpa_supplicant_8-b498eb4eb44bd696cbe520c516881f9feb7ecdce.zip | |
hostapd: Filter channel list updated events after country code change
We were not filtering the EVENT_CHANNEL_LIST_CHANGED events based on the
regulatory hint initiator. So wait for EVENT_CHANNEL_LIST_CHANGED event
after our own change was triggered even when regulatory hint initiator
was the driver. This could result in the wait for the channel list to be
updated to be terminated before the real change has occurred and as
such, old channel list remaining in use when configuring
hostapd/wpa_supplicant country parameter. Fix this by filtering the
hints according to the initiator and only regulatory hints initiated by
user will be used to stop the wait.
CRs-Fixed: 570018
Git-commit:795baf773f6d53bae3cfae4df6edda63e5022344
Git-repo: git://w1.fi/srv/git/hostap.git
Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
Change-Id: I1498135bf949df27f6aeab75c41cebddbb9a89a7
conflicts are resolved manually for:
src/ap/hostapd.h
src/drivers/driver.h
| -rw-r--r-- | src/ap/drv_callbacks.c | 3 | ||||
| -rw-r--r-- | src/ap/hostapd.c | 4 | ||||
| -rw-r--r-- | src/ap/hostapd.h | 2 | ||||
| -rw-r--r-- | src/drivers/driver.h | 15 | ||||
| -rw-r--r-- | src/drivers/driver_nl80211.c | 28 |
5 files changed, 47 insertions, 5 deletions
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index 129ca818..4b8a1a9d 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -935,7 +935,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 f95f6c2d..3852d146 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -904,9 +904,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 48a1e944..73ea73e4 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -355,7 +355,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); /* utils.c */ int hostapd_register_probereq_cb(struct hostapd_data *hapd, diff --git a/src/drivers/driver.h b/src/drivers/driver.h index a3fc32d0..92db1575 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -37,6 +37,13 @@ #define HOSTAPD_CHAN_DFS_AVAILABLE 0x00000300 #define HOSTAPD_CHAN_DFS_MASK 0x00000300 +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 */ @@ -3981,6 +3988,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 f06af0b9..6e1e9e60 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -2563,6 +2563,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); @@ -2656,8 +2657,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"); |
