--- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -894,7 +894,7 @@ static int hostapd_ctrl_iface_bss_tm_req WPA_PUT_LE16(&bss_term_dur[10], atoi(end)); } - nei_len = ieee802_11_parse_candidate_list(cmd, nei_rep, + nei_len = ieee802_11_parse_candidate_list(cmd, sta, nei_rep, sizeof(nei_rep)); if (nei_len < 0) return -1; --- a/src/common/ieee802_11_common.c +++ b/src/common/ieee802_11_common.c @@ -2257,11 +2257,21 @@ int is_6ghz_psc_frequency(int freq) } -int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, - size_t nei_rep_len) +int ieee802_11_parse_candidate_list(const char *pos, struct sta_info *sta, + u8 *nei_rep, size_t nei_rep_len) { u8 *nei_pos = nei_rep; const char *end; +#ifdef CONFIG_MBO + u8 non_pref_chan = 0; + u8 *pref_pos = NULL; + int i; + + struct mbo_non_pref_chan_info *info = NULL; + + if (sta && sta->non_pref_chan) + info = sta->non_pref_chan; +#endif /* * BSS Transition Candidate List Entries - Neighbor Report elements @@ -2317,6 +2327,9 @@ int ieee802_11_parse_candidate_list(cons pos++; *nei_pos++ = atoi(pos); /* Channel Number */ +#ifdef CONFIG_MBO + non_pref_chan = atoi(pos); +#endif pos = os_strchr(pos, ','); if (pos == NULL) { wpa_printf(MSG_DEBUG, "Missing PHY Type"); @@ -2348,6 +2361,25 @@ int ieee802_11_parse_candidate_list(cons "Invalid neighbor subelement info"); return -1; } +#ifdef CONFIG_MBO + if (info) { + for (i = 0; i < (len / 2); i++) + if (nei_pos[i] == WNM_NEIGHBOR_BSS_TRANSITION_CANDIDATE && + nei_pos[i + 1] == 0x1) /* length */ + pref_pos = (nei_pos + i + 2); + + /* If STA had updated MBO non-pref chan report, + * use the same candidate preference value in the + * BSS Transition Candidate sub-element. + */ + for ( ; info ; info = info->next) + for (i = 0; i < info->num_channels; i++) + if (non_pref_chan == info->channels[i]) + *pref_pos = info->pref; + + info = sta->non_pref_chan; + } +#endif nei_pos += len / 2; pos = end; } --- a/src/common/ieee802_11_common.h +++ b/src/common/ieee802_11_common.h @@ -11,6 +11,7 @@ #include "defs.h" #include "ieee802_11_defs.h" +#include "ap/sta_info.h" struct element { u8 id; @@ -262,8 +263,8 @@ int is_6ghz_freq(int freq); int is_6ghz_op_class(u8 op_class); int is_6ghz_psc_frequency(int freq); -int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, - size_t nei_rep_len); +int ieee802_11_parse_candidate_list(const char *pos, struct sta_info *sta, + u8 *nei_rep, size_t nei_rep_len); int ieee802_11_ext_capab(const u8 *ie, unsigned int capab); int op_class_to_bandwidth(u8 op_class); --- a/wpa_supplicant/wnm_sta.c +++ b/wpa_supplicant/wnm_sta.c @@ -1621,7 +1621,7 @@ int wnm_send_bss_transition_mgmt_query(s return ret; } - ret = ieee802_11_parse_candidate_list(btm_candidates, + ret = ieee802_11_parse_candidate_list(btm_candidates, NULL, wpabuf_put(buf, 0), max_len); if (ret < 0) {