diff --git a/src/network.c b/src/network.c index 46205b97..d2203916 100644 --- a/src/network.c +++ b/src/network.c @@ -715,7 +715,7 @@ bool network_bss_add(struct network *network, struct scan_bss *bss) if (bss->rc_ie && !network->rc_ie) network->rc_ie = l_memdup(bss->rc_ie, bss->rc_ie[1] + 2); - if (bss->hs20_ie) + if (bss->hs20_capable) network->is_hs20 = true; return true; diff --git a/src/scan.c b/src/scan.c index b8c790d9..6804096f 100644 --- a/src/scan.c +++ b/src/scan.c @@ -741,9 +741,13 @@ static bool scan_parse_vendor_specific(struct scan_bss *bss, const void *data, bss->wpa = l_memdup(data - 2, len + 2); else if (!bss->osen && is_ie_wfa_ie(data, len, IE_WFA_OI_OSEN)) bss->osen = l_memdup(data - 2, len + 2); - else if (is_ie_wfa_ie(data, len, IE_WFA_OI_HS20_INDICATION)) - bss->hs20_ie = l_memdup(data - 2, len + 2); - else + else if (is_ie_wfa_ie(data, len, IE_WFA_OI_HS20_INDICATION)) { + if (ie_parse_hs20_indication_from_data(data - 2, len + 2, + &bss->hs20_version, NULL, NULL) < 0) + return false; + + bss->hs20_capable = true; + } else return false; return true; @@ -1132,7 +1136,6 @@ void scan_bss_free(struct scan_bss *bss) l_free(bss->p2p); l_free(bss->osen); l_free(bss->rc_ie); - l_free(bss->hs20_ie); l_free(bss); } diff --git a/src/scan.h b/src/scan.h index 4d482681..d2c336b8 100644 --- a/src/scan.h +++ b/src/scan.h @@ -66,7 +66,7 @@ struct scan_bss { uint64_t time_stamp; uint8_t hessid[6]; uint8_t *rc_ie; /* Roaming consortium IE */ - uint8_t *hs20_ie; + uint8_t hs20_version; bool mde_present : 1; bool cc_present : 1; bool cap_rm_neighbor_report : 1; @@ -74,6 +74,7 @@ struct scan_bss { bool ht_capable : 1; bool vht_capable : 1; bool anqp_capable : 1; + bool hs20_capable : 1; }; struct scan_parameters { diff --git a/src/station.c b/src/station.c index 9f881cfd..cb2537d0 100644 --- a/src/station.c +++ b/src/station.c @@ -460,7 +460,7 @@ static bool station_start_anqp(struct station *station, struct network *network, struct anqp_entry *entry; bool anqp_disabled = true; - if (!bss->hs20_ie) + if (!bss->hs20_capable) return false; /* Network already has ANQP data/HESSID */ @@ -2181,6 +2181,7 @@ int __station_connect_network(struct station *station, struct network *network, struct scan_bss *bss) { const uint8_t *rc = NULL; + uint8_t hs20_ie[7]; size_t rc_len = 0; uint8_t rc_buf[32]; struct iovec iov[2]; @@ -2192,10 +2193,12 @@ int __station_connect_network(struct station *station, struct network *network, if (!hs) return -ENOTSUP; - if (bss->hs20_ie) { + if (bss->hs20_capable) { /* Include HS20 Indication with (Re)Association */ - iov[iov_elems].iov_base = bss->hs20_ie; - iov[iov_elems].iov_len = bss->hs20_ie[1] + 2; + ie_build_hs20_indication(bss->hs20_version, hs20_ie); + + iov[iov_elems].iov_base = hs20_ie; + iov[iov_elems].iov_len = hs20_ie[1] + 2; iov_elems++; /*