X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=wpa_supplicant%2Fwpa_supplicant.c;h=6999bbb466653ed29034fdfc3b086bd6e220a3eb;hb=4d7aab78bd11d6ff15f769761221e67b1160e562;hp=1f0fcd0ac77014baf9bfe7d002b1b4f9c160de80;hpb=d41a5352fec5caabb4643ccfaeca79b0346db34b;p=mech_eap.git diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 1f0fcd0..6999bbb 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -575,6 +575,9 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) #endif /* CONFIG_MBO */ free_bss_tmp_disallowed(wpa_s); + + wpabuf_free(wpa_s->lci); + wpa_s->lci = NULL; } @@ -2036,6 +2039,16 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s, if (chwidth == VHT_CHANWIDTH_80P80MHZ) break; } + } else if (ssid->max_oper_chwidth == VHT_CHANWIDTH_160MHZ) { + if (freq->freq == 5180) { + chwidth = VHT_CHANWIDTH_160MHZ; + vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; + seg0 = 50; + } else if (freq->freq == 5520) { + chwidth = VHT_CHANWIDTH_160MHZ; + vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; + seg0 = 114; + } } if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq, @@ -2288,6 +2301,11 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) * element in all cases, it is justifiable to skip it to avoid * interoperability issues. */ + if (ssid->p2p_group) + wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_CLIENT); + else + wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION); + if (!bss || wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB)) { u8 ext_capab[18]; int ext_capab_len; @@ -3788,8 +3806,8 @@ void wpa_supplicant_apply_vht_overrides( if (!vhtcaps || !vhtcaps_mask) return; - vhtcaps->vht_capabilities_info = ssid->vht_capa; - vhtcaps_mask->vht_capabilities_info = ssid->vht_capa_mask; + vhtcaps->vht_capabilities_info = host_to_le32(ssid->vht_capa); + vhtcaps_mask->vht_capabilities_info = host_to_le32(ssid->vht_capa_mask); #ifdef CONFIG_HT_OVERRIDES /* if max ampdu is <= 3, we have to make the HT cap the same */ @@ -3811,15 +3829,17 @@ void wpa_supplicant_apply_vht_overrides( #define OVERRIDE_MCS(i) \ if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \ vhtcaps_mask->vht_supported_mcs_set.tx_map |= \ - 3 << 2 * (i - 1); \ + host_to_le16(3 << 2 * (i - 1)); \ vhtcaps->vht_supported_mcs_set.tx_map |= \ - ssid->vht_tx_mcs_nss_ ##i << 2 * (i - 1); \ + host_to_le16(ssid->vht_tx_mcs_nss_ ##i << \ + 2 * (i - 1)); \ } \ if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \ vhtcaps_mask->vht_supported_mcs_set.rx_map |= \ - 3 << 2 * (i - 1); \ + host_to_le16(3 << 2 * (i - 1)); \ vhtcaps->vht_supported_mcs_set.rx_map |= \ - ssid->vht_rx_mcs_nss_ ##i << 2 * (i - 1); \ + host_to_le16(ssid->vht_rx_mcs_nss_ ##i << \ + 2 * (i - 1)); \ } OVERRIDE_MCS(1); @@ -3991,8 +4011,9 @@ static void wpas_fst_update_mb_ie_cb(void *ctx, const u8 *addr, } -const u8 * wpas_fst_get_peer_first(void *ctx, struct fst_get_peer_ctx **get_ctx, - Boolean mb_only) +static const u8 * wpas_fst_get_peer_first(void *ctx, + struct fst_get_peer_ctx **get_ctx, + Boolean mb_only) { struct wpa_supplicant *wpa_s = ctx; @@ -4004,8 +4025,9 @@ const u8 * wpas_fst_get_peer_first(void *ctx, struct fst_get_peer_ctx **get_ctx, } -const u8 * wpas_fst_get_peer_next(void *ctx, struct fst_get_peer_ctx **get_ctx, - Boolean mb_only) +static const u8 * wpas_fst_get_peer_next(void *ctx, + struct fst_get_peer_ctx **get_ctx, + Boolean mb_only) { return NULL; } @@ -5822,6 +5844,19 @@ int wpas_get_ssid_pmf(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) return NO_MGMT_FRAME_PROTECTION; } + if (ssid && + (ssid->key_mgmt & + ~(WPA_KEY_MGMT_NONE | WPA_KEY_MGMT_WPS | + WPA_KEY_MGMT_IEEE8021X_NO_WPA)) == 0) { + /* + * Do not use the default PMF value for non-RSN networks + * since PMF is available only with RSN and pmf=2 + * configuration would otherwise prevent connections to + * all open networks. + */ + return NO_MGMT_FRAME_PROTECTION; + } + return wpa_s->conf->pmf; } @@ -6340,6 +6375,147 @@ int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s, } +static struct wpabuf * wpas_rrm_build_lci_report(struct wpa_supplicant *wpa_s, + const u8 *request, size_t len, + struct wpabuf *report) +{ + u8 token, type, subject; + u16 max_age = 0; + struct os_reltime t, diff; + unsigned long diff_l; + u8 *ptoken; + const u8 *subelem; + + if (!wpa_s->lci || len < 3 + 4) + return report; + + token = *request++; + /* Measurement request mode isn't used */ + request++; + type = *request++; + subject = *request++; + + wpa_printf(MSG_DEBUG, + "Measurement request token %u type %u location subject %u", + token, type, subject); + + if (type != MEASURE_TYPE_LCI || subject != LOCATION_SUBJECT_REMOTE) { + wpa_printf(MSG_INFO, + "Not building LCI report - bad type or location subject"); + return report; + } + + /* Subelements are formatted exactly like elements */ + subelem = get_ie(request, len, LCI_REQ_SUBELEM_MAX_AGE); + if (subelem && subelem[1] == 2) + max_age = WPA_GET_LE16(subelem + 2); + + if (os_get_reltime(&t)) + return report; + + os_reltime_sub(&t, &wpa_s->lci_time, &diff); + /* LCI age is calculated in 10th of a second units. */ + diff_l = diff.sec * 10 + diff.usec / 100000; + + if (max_age != 0xffff && max_age < diff_l) + return report; + + if (wpabuf_resize(&report, 2 + wpabuf_len(wpa_s->lci))) + return report; + + wpabuf_put_u8(report, WLAN_EID_MEASURE_REPORT); + wpabuf_put_u8(report, wpabuf_len(wpa_s->lci)); + /* We'll override user's measurement token */ + ptoken = wpabuf_put(report, 0); + wpabuf_put_buf(report, wpa_s->lci); + *ptoken = token; + + return report; +} + + +void wpas_rrm_handle_radio_measurement_request(struct wpa_supplicant *wpa_s, + const u8 *src, + const u8 *frame, size_t len) +{ + struct wpabuf *buf, *report; + u8 token; + const u8 *ie, *end; + + if (wpa_s->wpa_state != WPA_COMPLETED) { + wpa_printf(MSG_INFO, + "RRM: Ignoring radio measurement request: Not associated"); + return; + } + + if (!wpa_s->rrm.rrm_used) { + wpa_printf(MSG_INFO, + "RRM: Ignoring radio measurement request: Not RRM network"); + return; + } + + if (len < 3) { + wpa_printf(MSG_INFO, + "RRM: Ignoring too short radio measurement request"); + return; + } + + end = frame + len; + + token = *frame++; + + /* Ignore number of repetitions because it's not used in LCI request */ + frame += 2; + + report = NULL; + while ((ie = get_ie(frame, end - frame, WLAN_EID_MEASURE_REQUEST)) && + ie[1] >= 3) { + u8 msmt_type; + + msmt_type = ie[4]; + wpa_printf(MSG_DEBUG, "RRM request %d", msmt_type); + + switch (msmt_type) { + case MEASURE_TYPE_LCI: + report = wpas_rrm_build_lci_report(wpa_s, ie + 2, ie[1], + report); + break; + default: + wpa_printf(MSG_INFO, + "RRM: Unsupported radio measurement request %d", + msmt_type); + break; + } + + frame = ie + ie[1] + 2; + } + + if (!report) + return; + + buf = wpabuf_alloc(3 + wpabuf_len(report)); + if (!buf) { + wpabuf_free(report); + return; + } + + wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT); + wpabuf_put_u8(buf, WLAN_RRM_RADIO_MEASUREMENT_REPORT); + wpabuf_put_u8(buf, token); + + wpabuf_put_buf(buf, report); + wpabuf_free(report); + + if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, src, + wpa_s->own_addr, wpa_s->bssid, + wpabuf_head(buf), wpabuf_len(buf), 0)) { + wpa_printf(MSG_ERROR, + "RRM: Radio measurement report failed: Sending Action frame failed"); + } + wpabuf_free(buf); +} + + void wpas_rrm_handle_link_measurement_request(struct wpa_supplicant *wpa_s, const u8 *src, const u8 *frame, size_t len,