/*
 * AP mode helper functions
 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"

#include "common.h"
#include "common/ieee802_11_defs.h"
#include "fst/fst.h"
#include "sta_info.h"
#include "hostapd.h"


int hostapd_register_probereq_cb(struct hostapd_data *hapd,
				 int (*cb)(void *ctx, const u8 *sa,
					   const u8 *da, const u8 *bssid,
					   const u8 *ie, size_t ie_len,
					   int ssi_signal),
				 void *ctx)
{
	struct hostapd_probereq_cb *n;

	n = os_realloc_array(hapd->probereq_cb, hapd->num_probereq_cb + 1,
			     sizeof(struct hostapd_probereq_cb));
	if (n == NULL)
		return -1;

	hapd->probereq_cb = n;
	n = &hapd->probereq_cb[hapd->num_probereq_cb];
	hapd->num_probereq_cb++;

	n->cb = cb;
	n->ctx = ctx;

	return 0;
}


struct prune_data {
	struct hostapd_data *hapd;
	const u8 *addr;
	int mld_assoc_link_id;
};

static int prune_associations(struct hostapd_iface *iface, void *ctx)
{
	struct prune_data *data = ctx;
	struct sta_info *osta;
	struct hostapd_data *ohapd;
	size_t j;

	for (j = 0; j < iface->num_bss; j++) {
		ohapd = iface->bss[j];
		if (ohapd == data->hapd)
			continue;
#ifdef CONFIG_TESTING_OPTIONS
		if (ohapd->conf->skip_prune_assoc)
			continue;
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_FST
		/* Don't prune STAs belong to same FST */
		if (ohapd->iface->fst &&
		    data->hapd->iface->fst &&
		    fst_are_ifaces_aggregated(ohapd->iface->fst,
					      data->hapd->iface->fst))
			continue;
#endif /* CONFIG_FST */
		osta = ap_get_sta(ohapd, data->addr);
		if (!osta)
			continue;

#ifdef CONFIG_IEEE80211BE
		if (data->mld_assoc_link_id >= 0 &&
		    osta->mld_assoc_link_id == data->mld_assoc_link_id)
			continue;
#endif /* CONFIG_IEEE80211BE */

		wpa_printf(MSG_INFO, "%s: Prune association for " MACSTR,
			   ohapd->conf->iface, MAC2STR(osta->addr));
		ap_sta_disassociate(ohapd, osta, WLAN_REASON_UNSPECIFIED);
	}

	return 0;
}

/**
 * hostapd_prune_associations - Remove extraneous associations
 * @hapd: Pointer to BSS data for the most recent association
 * @addr: Associated STA address
 * @mld_assoc_link_id: MLD link id used for association or -1 for non MLO
 *
 * This function looks through all radios and BSS's for previous
 * (stale) associations of STA. If any are found they are removed.
 */
void hostapd_prune_associations(struct hostapd_data *hapd, const u8 *addr,
				int mld_assoc_link_id)
{
	struct prune_data data;

	data.hapd = hapd;
	data.addr = addr;
	data.mld_assoc_link_id = mld_assoc_link_id;

	if (hapd->iface->interfaces &&
	    hapd->iface->interfaces->for_each_interface)
		hapd->iface->interfaces->for_each_interface(
			hapd->iface->interfaces, prune_associations, &data);
}
