RNR: Add co-located BSSes
Calculate the length and include data for the BSSes active on the same radio as the reporting BSS in the Reduced Neighbor Report element. This element is included in Beacon and Probe Response frames. Signed-off-by: John Crispin <john@phrozen.org> Co-developed-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org> Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org> Co-developed-by: Muna Sinada <msinada@codeaurora.org> Signed-off-by: Muna Sinada <msinada@codeaurora.org> Co-developed-by: Aloka Dixit <alokad@codeaurora.org> Signed-off-by: Aloka Dixit <alokad@codeaurora.org>
This commit is contained in:
parent
a7c152d6b8
commit
b2bbedcb21
1 changed files with 146 additions and 0 deletions
|
@ -7102,6 +7102,54 @@ static size_t hostapd_eid_nr_db_len(struct hostapd_data *hapd,
|
|||
}
|
||||
|
||||
|
||||
static size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
|
||||
struct hostapd_data *reporting_hapd,
|
||||
size_t *current_len)
|
||||
{
|
||||
size_t total_len = 0, len = *current_len;
|
||||
int tbtt_count = 0;
|
||||
size_t i, start = 0;
|
||||
|
||||
while (start < hapd->iface->num_bss) {
|
||||
if (!len ||
|
||||
len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
|
||||
len = RNR_HEADER_LEN;
|
||||
total_len += RNR_HEADER_LEN;
|
||||
}
|
||||
|
||||
len += RNR_TBTT_HEADER_LEN;
|
||||
total_len += RNR_TBTT_HEADER_LEN;
|
||||
|
||||
for (i = start; i < hapd->iface->num_bss; i++) {
|
||||
struct hostapd_data *bss = hapd->iface->bss[i];
|
||||
|
||||
if (!bss || !bss->conf || !bss->started)
|
||||
continue;
|
||||
|
||||
if (bss == reporting_hapd ||
|
||||
bss->conf->ignore_broadcast_ssid)
|
||||
continue;
|
||||
|
||||
if (len + RNR_TBTT_INFO_LEN > 255 ||
|
||||
tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
|
||||
break;
|
||||
|
||||
len += RNR_TBTT_INFO_LEN;
|
||||
total_len += RNR_TBTT_INFO_LEN;
|
||||
tbtt_count++;
|
||||
}
|
||||
start = i;
|
||||
}
|
||||
|
||||
if (!tbtt_count)
|
||||
total_len = 0;
|
||||
else
|
||||
*current_len = len;
|
||||
|
||||
return total_len;
|
||||
}
|
||||
|
||||
|
||||
size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
|
||||
{
|
||||
size_t total_len = 0, current_len = 0;
|
||||
|
@ -7110,6 +7158,12 @@ size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
|
|||
case WLAN_FC_STYPE_BEACON:
|
||||
if (hapd->conf->rnr)
|
||||
total_len += hostapd_eid_nr_db_len(hapd, ¤t_len);
|
||||
/* fallthrough */
|
||||
|
||||
case WLAN_FC_STYPE_PROBE_RESP:
|
||||
if (hapd->conf->rnr && hapd->iface->num_bss > 1)
|
||||
total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
|
||||
¤t_len);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -7175,6 +7229,92 @@ static u8 * hostapd_eid_nr_db(struct hostapd_data *hapd, u8 *eid,
|
|||
}
|
||||
|
||||
|
||||
static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
|
||||
struct hostapd_data *reporting_hapd,
|
||||
u8 *eid, size_t *current_len)
|
||||
{
|
||||
struct hostapd_data *bss;
|
||||
struct hostapd_iface *iface = hapd->iface;
|
||||
size_t i, start = 0;
|
||||
size_t len = *current_len;
|
||||
u8 *tbtt_count_pos, *eid_start = eid, *size_offset = (eid - len) + 1;
|
||||
u8 tbtt_count = 0, op_class, channel, bss_param;
|
||||
|
||||
if (!(iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA) || !iface->freq)
|
||||
return eid;
|
||||
|
||||
if (ieee80211_freq_to_channel_ext(iface->freq,
|
||||
hapd->iconf->secondary_channel,
|
||||
hostapd_get_oper_chwidth(hapd->iconf),
|
||||
&op_class, &channel) ==
|
||||
NUM_HOSTAPD_MODES)
|
||||
return eid;
|
||||
|
||||
while (start < iface->num_bss) {
|
||||
if (!len ||
|
||||
len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
|
||||
eid_start = eid;
|
||||
*eid++ = WLAN_EID_REDUCED_NEIGHBOR_REPORT;
|
||||
size_offset = eid++;
|
||||
len = RNR_HEADER_LEN;
|
||||
tbtt_count = 0;
|
||||
}
|
||||
|
||||
tbtt_count_pos = eid++;
|
||||
*eid++ = RNR_TBTT_INFO_LEN;
|
||||
*eid++ = op_class;
|
||||
*eid++ = hapd->iconf->channel;
|
||||
len += RNR_TBTT_HEADER_LEN;
|
||||
|
||||
for (i = start; i < iface->num_bss; i++) {
|
||||
bss_param = 0;
|
||||
bss = iface->bss[i];
|
||||
if (!bss || !bss->conf || !bss->started)
|
||||
continue;
|
||||
|
||||
if (bss == reporting_hapd ||
|
||||
bss->conf->ignore_broadcast_ssid)
|
||||
continue;
|
||||
|
||||
if (len + RNR_TBTT_INFO_LEN > 255 ||
|
||||
tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
|
||||
break;
|
||||
|
||||
*eid++ = RNR_NEIGHBOR_AP_OFFSET_UNKNOWN;
|
||||
os_memcpy(eid, bss->conf->bssid, ETH_ALEN);
|
||||
eid += ETH_ALEN;
|
||||
os_memcpy(eid, &bss->conf->ssid.short_ssid, 4);
|
||||
eid += 4;
|
||||
if (bss->conf->ssid.short_ssid ==
|
||||
reporting_hapd->conf->ssid.short_ssid)
|
||||
bss_param |= RNR_BSS_PARAM_SAME_SSID;
|
||||
|
||||
if (is_6ghz_op_class(hapd->iconf->op_class) &&
|
||||
bss->conf->unsol_bcast_probe_resp_interval)
|
||||
bss_param |=
|
||||
RNR_BSS_PARAM_UNSOLIC_PROBE_RESP_ACTIVE;
|
||||
|
||||
bss_param |= RNR_BSS_PARAM_CO_LOCATED;
|
||||
|
||||
*eid++ = bss_param;
|
||||
*eid++ = RNR_20_MHZ_PSD_MAX_TXPOWER - 1;
|
||||
len += RNR_TBTT_INFO_LEN;
|
||||
tbtt_count += 1;
|
||||
}
|
||||
|
||||
start = i;
|
||||
*tbtt_count_pos = RNR_TBTT_INFO_COUNT(tbtt_count - 1);
|
||||
*size_offset = (eid - size_offset) - 1;
|
||||
}
|
||||
|
||||
if (tbtt_count == 0)
|
||||
return eid_start;
|
||||
|
||||
*current_len = len;
|
||||
return eid;
|
||||
}
|
||||
|
||||
|
||||
u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
|
||||
{
|
||||
u8 *eid_start = eid;
|
||||
|
@ -7184,6 +7324,12 @@ u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
|
|||
case WLAN_FC_STYPE_BEACON:
|
||||
if (hapd->conf->rnr)
|
||||
eid = hostapd_eid_nr_db(hapd, eid, ¤t_len);
|
||||
/* fallthrough */
|
||||
|
||||
case WLAN_FC_STYPE_PROBE_RESP:
|
||||
if (hapd->conf->rnr && hapd->iface->num_bss > 1)
|
||||
eid = hostapd_eid_rnr_iface(hapd, hapd, eid,
|
||||
¤t_len);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue