On a connect nl80211 event, wpa_supplicant uses wpa_driver_ nl80211_get_ssid() to fetch the current associated ssid to compare to existing configurations. However, wpa_driver_nl80211_get_ssid() uses drv->ssid, which is a cached value. It is set when we explicitly initial a connect request using wpa_supplicant. if the association was initiated outside of wpa_supplicant, we need another way to populate drv->ssid. This patch sets drv->ssid passively on connect/associate nl80211 events. Signed-off-by: Ningyuan Wang <nywang@xxxxxxxxxx> --- src/drivers/driver_nl80211.c | 21 +++++++++++++++++++++ src/drivers/driver_nl80211.h | 3 +++ src/drivers/driver_nl80211_event.c | 15 +++++++++++++++ src/drivers/driver_nl80211_scan.c | 15 +++++++++++++-- 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 1210d43..d8b0ebf 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -1181,6 +1181,27 @@ static void wpa_driver_nl80211_event_rtm_dellink(void *ctx, } +unsigned int nl80211_get_assoc_ssid(struct wpa_driver_nl80211_data *drv, u8* ssid) +{ + struct nl_msg *msg; + int ret; + struct nl80211_bss_info_arg arg; + + msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SCAN); + os_memset(&arg, 0, sizeof(arg)); + arg.drv = drv; + ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg); + if (ret == 0) { + if (arg.assoc_ssid_len == 0) + return 0; + os_memcpy(ssid, arg.assoc_ssid, arg.assoc_ssid_len); + return arg.assoc_ssid_len; + } + wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d " + "(%s)", ret, strerror(-ret)); + return 0; +} + unsigned int nl80211_get_assoc_freq(struct wpa_driver_nl80211_data *drv) { struct nl_msg *msg; diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h index d0ec48c..db843ad 100644 --- a/src/drivers/driver_nl80211.h +++ b/src/drivers/driver_nl80211.h @@ -228,6 +228,7 @@ int nl80211_create_iface(struct wpa_driver_nl80211_data *drv, void *arg, int use_existing); void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv, int ifidx); unsigned int nl80211_get_assoc_freq(struct wpa_driver_nl80211_data *drv); +unsigned int nl80211_get_assoc_ssid(struct wpa_driver_nl80211_data *drv, u8* ssid); enum chan_width convert2width(int width); void nl80211_mark_disconnected(struct wpa_driver_nl80211_data *drv); struct i802_bss * get_bss_ifindex(struct wpa_driver_nl80211_data *drv, @@ -288,6 +289,8 @@ struct nl80211_bss_info_arg { unsigned int assoc_freq; unsigned int ibss_freq; u8 assoc_bssid[ETH_ALEN]; + u8 assoc_ssid[SSID_MAX_LEN]; + u8 assoc_ssid_len; }; int bss_info_handler(struct nl_msg *msg, void *arg); diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c index 762e3ac..41305bc 100644 --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -255,6 +255,14 @@ static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv, event.assoc_info.freq = drv->assoc_freq; +#ifdef ANDROID + // When this associate event was initiated outside of wpa_supplicant, + // drv->ssid needs to be set here to satisfy later checking. + u8 ssid_len = nl80211_get_assoc_ssid(drv, drv->ssid); + if (ssid_len) drv->ssid_len = ssid_len; +#endif /* ANDROID */ + + nl80211_parse_wmm_params(wmm, &event.assoc_info.wmm_params); wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event); @@ -355,6 +363,13 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv, event.assoc_info.freq = nl80211_get_assoc_freq(drv); +#ifdef ANDROID + // When this connect event was initiated outside of wpa_supplicant, + // drv->ssid needs to be set here to satisfy later checking. + u8 ssid_len = nl80211_get_assoc_ssid(drv, drv->ssid); + if (ssid_len) drv->ssid_len = ssid_len; +#endif /* ANDROID */ + if (authorized && nla_get_u8(authorized)) { event.assoc_info.authorized = 1; wpa_printf(MSG_DEBUG, "nl80211: connection authorized"); diff --git a/src/drivers/driver_nl80211_scan.c b/src/drivers/driver_nl80211_scan.c index c115b6b..3084695 100644 --- a/src/drivers/driver_nl80211_scan.c +++ b/src/drivers/driver_nl80211_scan.c @@ -621,15 +621,26 @@ int bss_info_handler(struct nl_msg *msg, void *arg) MACSTR, MAC2STR(_arg->assoc_bssid)); } } - if (!res) - return NL_SKIP; if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) { ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]); ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]); + enum nl80211_bss_status status; + if (bss[NL80211_BSS_STATUS]) { + status = nla_get_u32(bss[NL80211_BSS_STATUS]); + if (status == NL80211_BSS_STATUS_ASSOCIATED && ie) { + const u8* ssid = get_ie(ie, ie_len, WLAN_EID_SSID); + if (ssid && ssid[1] > 0 && ssid[1] <= SSID_MAX_LEN) { + _arg->assoc_ssid_len = ssid[1]; + os_memcpy(_arg->assoc_ssid, ssid + 2, ssid[1]); + } + } + } } else { ie = NULL; ie_len = 0; } + if (!res) + return NL_SKIP; if (bss[NL80211_BSS_BEACON_IES]) { beacon_ie = nla_data(bss[NL80211_BSS_BEACON_IES]); beacon_ie_len = nla_len(bss[NL80211_BSS_BEACON_IES]); -- 2.8.0.rc3.226.g39d4020 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap