{
struct hostapd_iface *iface = hapd->iface;
struct hostapd_data *tx_bss;
- size_t len;
+ size_t len, rnr_len = 0;
u8 elem_count = 0, *elem = NULL, **elem_offset = NULL, *end;
+ u8 rnr_elem_count = 0, *rnr_elem = NULL, **rnr_elem_offset = NULL;
if (!iface->mbssid_max_interfaces ||
iface->num_bss > iface->mbssid_max_interfaces ||
tx_bss = hostapd_mbssid_get_tx_bss(hapd);
len = hostapd_eid_mbssid_len(tx_bss, WLAN_FC_STYPE_BEACON, &elem_count,
- NULL, 0);
+ NULL, 0, &rnr_len);
if (!len || (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED &&
elem_count > iface->ema_max_periodicity))
goto fail;
if (!elem_offset)
goto fail;
+ if (rnr_len) {
+ rnr_elem = os_zalloc(rnr_len);
+ if (!rnr_elem)
+ goto fail;
+
+ rnr_elem_offset = os_calloc(elem_count + 1, sizeof(u8 *));
+ if (!rnr_elem_offset)
+ goto fail;
+ }
+
end = hostapd_eid_mbssid(tx_bss, elem, elem + len, WLAN_FC_STYPE_BEACON,
- elem_count, elem_offset, NULL, 0);
+ elem_count, elem_offset, NULL, 0, rnr_elem,
+ &rnr_elem_count, rnr_elem_offset, rnr_len);
params->mbssid_tx_iface = tx_bss->conf->iface;
params->mbssid_index = hostapd_mbssid_get_bss_index(hapd);
params->mbssid_elem_len = end - elem;
params->mbssid_elem_count = elem_count;
params->mbssid_elem_offset = elem_offset;
+ params->rnr_elem = rnr_elem;
+ params->rnr_elem_len = rnr_len;
+ params->rnr_elem_count = rnr_elem_count;
+ params->rnr_elem_offset = rnr_elem_offset;
if (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED)
params->ema = true;
return 0;
fail:
+ os_free(rnr_elem);
+ os_free(rnr_elem_offset);
+ os_free(elem_offset);
os_free(elem);
wpa_printf(MSG_ERROR, "MBSSID: Configuration failed");
return -1;
#endif /* CONFIG_IEEE80211BE */
buflen += hostapd_eid_mbssid_len(hapd, WLAN_FC_STYPE_PROBE_RESP, NULL,
- known_bss, known_bss_len);
+ known_bss, known_bss_len, NULL);
buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP);
buflen += hostapd_mbo_ie_len(hapd);
buflen += hostapd_eid_owe_trans_len(hapd);
pos = hostapd_get_rsne(hapd, pos, epos - pos);
pos = hostapd_eid_bss_load(hapd, pos, epos - pos);
pos = hostapd_eid_mbssid(hapd, pos, epos, WLAN_FC_STYPE_PROBE_RESP, 0,
- NULL, known_bss, known_bss_len);
+ NULL, known_bss, known_bss_len, NULL, NULL,
+ NULL, 0);
pos = hostapd_eid_rm_enabled_capab(hapd, pos, epos - pos);
pos = hostapd_get_mde(hapd, pos, epos - pos);
params->mbssid_elem = NULL;
os_free(params->mbssid_elem_offset);
params->mbssid_elem_offset = NULL;
+ os_free(params->rnr_elem);
+ params->rnr_elem = NULL;
+ os_free(params->rnr_elem_offset);
+ params->rnr_elem_offset = NULL;
#ifdef CONFIG_FILS
os_free(params->fd_frame_tmpl);
params->fd_frame_tmpl = NULL;
}
-static size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
- struct hostapd_data *reporting_hapd,
- size_t *current_len)
+struct mbssid_ie_profiles {
+ u8 start;
+ u8 end;
+};
+
+static size_t
+hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
+ struct hostapd_data *reporting_hapd,
+ size_t *current_len,
+ struct mbssid_ie_profiles *skip_profiles)
{
size_t total_len = 0, len = *current_len;
int tbtt_count = 0;
bss->conf->ignore_broadcast_ssid)
continue;
+ if (skip_profiles &&
+ i >= skip_profiles->start && i < skip_profiles->end)
+ continue;
+
if (len + RNR_TBTT_INFO_LEN > 255 ||
tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
break;
continue;
len += hostapd_eid_rnr_iface_len(iface->bss[0], hapd,
- current_len);
+ current_len, NULL);
}
return len;
if (hapd->conf->rnr && hapd->iface->num_bss > 1 &&
!hapd->iconf->mbssid)
total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
- ¤t_len);
+ ¤t_len,
+ NULL);
break;
case WLAN_FC_STYPE_ACTION:
if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ)
total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
- ¤t_len);
+ ¤t_len,
+ NULL);
break;
default:
static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
struct hostapd_data *reporting_hapd,
- u8 *eid, size_t *current_len)
+ u8 *eid, size_t *current_len,
+ struct mbssid_ie_profiles *skip_profiles)
{
struct hostapd_data *bss;
struct hostapd_iface *iface = hapd->iface;
bss->conf->ignore_broadcast_ssid)
continue;
+ if (skip_profiles &&
+ i >= skip_profiles->start && i < skip_profiles->end)
+ continue;
+
if (len + RNR_TBTT_INFO_LEN > 255 ||
tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
break;
if (iface->conf->mbssid != MBSSID_DISABLED &&
iface->num_bss > 1) {
bss_param |= RNR_BSS_PARAM_MULTIPLE_BSSID;
- if (i == 0)
+ if (bss == hostapd_mbssid_get_tx_bss(hapd))
bss_param |=
RNR_BSS_PARAM_TRANSMITTED_BSSID;
}
continue;
eid = hostapd_eid_rnr_iface(iface->bss[0], hapd, eid,
- current_len);
+ current_len, NULL);
}
return eid;
if (hapd->conf->rnr && hapd->iface->num_bss > 1 &&
!hapd->iconf->mbssid)
eid = hostapd_eid_rnr_iface(hapd, hapd, eid,
- ¤t_len);
+ ¤t_len, NULL);
break;
case WLAN_FC_STYPE_ACTION:
if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ)
eid = hostapd_eid_rnr_iface(hapd, hapd, eid,
- ¤t_len);
+ ¤t_len, NULL);
break;
default:
size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type,
u8 *elem_count, const u8 *known_bss,
- size_t known_bss_len)
+ size_t known_bss_len, size_t *rnr_len)
{
size_t len = 0, bss_index = 1;
}
while (bss_index < hapd->iface->num_bss) {
+ size_t rnr_count = bss_index;
+
len += hostapd_eid_mbssid_elem_len(hapd, frame_type,
&bss_index, known_bss,
known_bss_len);
if (frame_type == WLAN_FC_STYPE_BEACON)
*elem_count += 1;
+ if (hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED && rnr_len) {
+ size_t rnr_cur_len = 0;
+ struct mbssid_ie_profiles skip_profiles = {
+ rnr_count, bss_index
+ };
+
+ *rnr_len += hostapd_eid_rnr_iface_len(
+ hapd, hostapd_mbssid_get_tx_bss(hapd),
+ &rnr_cur_len, &skip_profiles);
+ }
}
+
+ if (hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED && rnr_len)
+ *rnr_len += hostapd_eid_rnr_len(hapd, frame_type);
+
return len;
}
u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
unsigned int frame_stype, u8 elem_count,
u8 **elem_offset,
- const u8 *known_bss, size_t known_bss_len)
+ const u8 *known_bss, size_t known_bss_len, u8 *rnr_eid,
+ u8 *rnr_count, u8 **rnr_offset, size_t rnr_len)
{
- size_t bss_index = 1;
- u8 elem_index = 0;
+ size_t bss_index = 1, cur_len = 0;
+ u8 elem_index = 0, *rnr_start_eid = rnr_eid;
+ bool add_rnr;
if (!hapd->iconf->mbssid || hapd->iface->num_bss <= 1 ||
(frame_stype != WLAN_FC_STYPE_BEACON &&
return eid;
}
+ add_rnr = hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED &&
+ frame_stype == WLAN_FC_STYPE_BEACON &&
+ rnr_eid && rnr_count && rnr_offset && rnr_len;
+
while (bss_index < hapd->iface->num_bss) {
+ unsigned int rnr_start_count = bss_index;
+
if (frame_stype == WLAN_FC_STYPE_BEACON) {
if (elem_index == elem_count) {
wpa_printf(MSG_WARNING,
hostapd_max_bssid_indicator(hapd),
&bss_index, elem_count,
known_bss, known_bss_len);
+
+ if (add_rnr) {
+ struct mbssid_ie_profiles skip_profiles = {
+ rnr_start_count, bss_index
+ };
+
+ rnr_offset[*rnr_count] = rnr_eid;
+ *rnr_count = *rnr_count + 1;
+ cur_len = 0;
+ rnr_eid = hostapd_eid_rnr_iface(
+ hapd, hostapd_mbssid_get_tx_bss(hapd),
+ rnr_eid, &cur_len, &skip_profiles);
+ }
+ }
+
+ if (add_rnr && (size_t) (rnr_eid - rnr_start_eid) < rnr_len) {
+ rnr_offset[*rnr_count] = rnr_eid;
+ *rnr_count = *rnr_count + 1;
+ cur_len = 0;
+
+ if (hapd->conf->rnr)
+ rnr_eid = hostapd_eid_nr_db(hapd, rnr_eid, &cur_len);
+ if (get_colocation_mode(hapd) == COLOCATED_LOWER_BAND)
+ rnr_eid = hostapd_eid_rnr_colocation(hapd, rnr_eid,
+ &cur_len);
}
return eid;