/*
 * hostapd / IEEE 802.11n HT
 * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
 * Copyright (c) 2007-2008, Intel Corporation
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "utils/includes.h"

#include "utils/common.h"
#include "utils/eloop.h"
#include "common/ieee802_11_defs.h"
#include "hostapd.h"
#include "ap_config.h"
#include "sta_info.h"
#include "beacon.h"
#include "ieee802_11.h"
#include "hw_features.h"
#include "ap_drv_ops.h"


u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid)
{
	struct ieee80211_ht_capabilities *cap;
	u8 *pos = eid;

	if (!hapd->iconf->ieee80211n || !hapd->iface->current_mode ||
	    hapd->conf->disable_11n)
		return eid;

	*pos++ = WLAN_EID_HT_CAP;
	*pos++ = sizeof(*cap);

	cap = (struct ieee80211_ht_capabilities *) pos;
	os_memset(cap, 0, sizeof(*cap));
	cap->ht_capabilities_info = host_to_le16(hapd->iconf->ht_capab);
	cap->a_mpdu_params = hapd->iface->current_mode->a_mpdu_params;
	os_memcpy(cap->supported_mcs_set, hapd->iface->current_mode->mcs_set,
		  16);

	/* TODO: ht_extended_capabilities (now fully disabled) */
	/* TODO: tx_bf_capability_info (now fully disabled) */
	/* TODO: asel_capabilities (now fully disabled) */

 	pos += sizeof(*cap);

	if (hapd->iconf->obss_interval) {
		struct ieee80211_obss_scan_parameters *scan_params;

		*pos++ = WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS;
		*pos++ = sizeof(*scan_params);

		scan_params = (struct ieee80211_obss_scan_parameters *) pos;
		os_memset(scan_params, 0, sizeof(*scan_params));
		scan_params->width_trigger_scan_interval =
			host_to_le16(hapd->iconf->obss_interval);

		/* Fill in default values for remaining parameters
		 * (IEEE Std 802.11-2012, 8.4.2.61 and MIB defval) */
		scan_params->scan_passive_dwell =
			host_to_le16(20);
		scan_params->scan_active_dwell =
			host_to_le16(10);
		scan_params->scan_passive_total_per_channel =
			host_to_le16(200);
		scan_params->scan_active_total_per_channel =
			host_to_le16(20);
		scan_params->channel_transition_delay_factor =
			host_to_le16(5);
		scan_params->scan_activity_threshold =
			host_to_le16(25);

		pos += sizeof(*scan_params);
	}

	return pos;
}


u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid)
{
	struct ieee80211_ht_operation *oper;
	u8 *pos = eid;

	if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n)
		return eid;

	*pos++ = WLAN_EID_HT_OPERATION;
	*pos++ = sizeof(*oper);

	oper = (struct ieee80211_ht_operation *) pos;
	os_memset(oper, 0, sizeof(*oper));

	oper->primary_chan = hapd->iconf->channel;
	oper->operation_mode = host_to_le16(hapd->iface->ht_op_mode);
	if (hapd->iconf->secondary_channel == 1)
		oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE |
			HT_INFO_HT_PARAM_STA_CHNL_WIDTH;
	if (hapd->iconf->secondary_channel == -1)
		oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW |
			HT_INFO_HT_PARAM_STA_CHNL_WIDTH;

	pos += sizeof(*oper);

	return pos;
}


/*
op_mode
Set to 0 (HT pure) under the followign conditions
	- all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
	- all STAs in the BSS are 20 MHz HT in 20 MHz BSS
Set to 1 (HT non-member protection) if there may be non-HT STAs
	in both the primary and the secondary channel
Set to 2 if only HT STAs are associated in BSS,
	however and at least one 20 MHz HT STA is associated
Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
*/
int hostapd_ht_operation_update(struct hostapd_iface *iface)
{
	u16 cur_op_mode, new_op_mode;
	int op_mode_changes = 0;

	if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed)
		return 0;

	wpa_printf(MSG_DEBUG, "%s current operation mode=0x%X",
		   __func__, iface->ht_op_mode);

	if (!(iface->ht_op_mode & HT_OPER_OP_MODE_NON_GF_HT_STAS_PRESENT)
	    && iface->num_sta_ht_no_gf) {
		iface->ht_op_mode |= HT_OPER_OP_MODE_NON_GF_HT_STAS_PRESENT;
		op_mode_changes++;
	} else if ((iface->ht_op_mode &
		    HT_OPER_OP_MODE_NON_GF_HT_STAS_PRESENT) &&
		   iface->num_sta_ht_no_gf == 0) {
		iface->ht_op_mode &= ~HT_OPER_OP_MODE_NON_GF_HT_STAS_PRESENT;
		op_mode_changes++;
	}

	if (!(iface->ht_op_mode & HT_OPER_OP_MODE_OBSS_NON_HT_STAS_PRESENT) &&
	    (iface->num_sta_no_ht || iface->olbc_ht)) {
		iface->ht_op_mode |= HT_OPER_OP_MODE_OBSS_NON_HT_STAS_PRESENT;
		op_mode_changes++;
	} else if ((iface->ht_op_mode &
		    HT_OPER_OP_MODE_OBSS_NON_HT_STAS_PRESENT) &&
		   (iface->num_sta_no_ht == 0 && !iface->olbc_ht)) {
		iface->ht_op_mode &= ~HT_OPER_OP_MODE_OBSS_NON_HT_STAS_PRESENT;
		op_mode_changes++;
	}

	if (iface->num_sta_no_ht)
		new_op_mode = HT_PROT_NON_HT_MIXED;
	else if (iface->conf->secondary_channel && iface->num_sta_ht_20mhz)
		new_op_mode = HT_PROT_20MHZ_PROTECTION;
	else if (iface->olbc_ht)
		new_op_mode = HT_PROT_NONMEMBER_PROTECTION;
	else
		new_op_mode = HT_PROT_NO_PROTECTION;

	cur_op_mode = iface->ht_op_mode & HT_OPER_OP_MODE_HT_PROT_MASK;
	if (cur_op_mode != new_op_mode) {
		iface->ht_op_mode &= ~HT_OPER_OP_MODE_HT_PROT_MASK;
		iface->ht_op_mode |= new_op_mode;
		op_mode_changes++;
	}

	wpa_printf(MSG_DEBUG, "%s new operation mode=0x%X changes=%d",
		   __func__, iface->ht_op_mode, op_mode_changes);

	return op_mode_changes;
}


static int is_40_allowed(struct hostapd_iface *iface, int channel)
{
	int pri_freq, sec_freq;
	int affected_start, affected_end;
	int pri = 2407 + 5 * channel;

	if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
		return 1;

	pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);

	if (iface->conf->secondary_channel > 0)
		sec_freq = pri_freq + 20;
	else
		sec_freq = pri_freq - 20;

	affected_start = (pri_freq + sec_freq) / 2 - 25;
	affected_end = (pri_freq + sec_freq) / 2 + 25;
	if ((pri < affected_start || pri > affected_end))
		return 1; /* not within affected channel range */

	wpa_printf(MSG_ERROR, "40 MHz affected channel range: [%d,%d] MHz",
		   affected_start, affected_end);
	wpa_printf(MSG_ERROR, "Neighboring BSS: freq=%d", pri);
	return 0;
}


void hostapd_2040_coex_action(struct hostapd_data *hapd,
			      const struct ieee80211_mgmt *mgmt, size_t len)
{
	struct hostapd_iface *iface = hapd->iface;
	struct ieee80211_2040_bss_coex_ie *bc_ie;
	struct ieee80211_2040_intol_chan_report *ic_report;
	int is_ht_allowed = 1;
	int i;
	const u8 *start = (const u8 *) mgmt;
	const u8 *data = start + IEEE80211_HDRLEN + 2;

	hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
		       HOSTAPD_LEVEL_DEBUG, "hostapd_public_action - action=%d",
		       mgmt->u.action.u.public_action.action);

	if (!(iface->conf->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
		return;

	if (len < IEEE80211_HDRLEN + 2 + sizeof(*bc_ie))
		return;

	bc_ie = (struct ieee80211_2040_bss_coex_ie *) data;
	if (bc_ie->element_id != WLAN_EID_20_40_BSS_COEXISTENCE ||
	    bc_ie->length < 1) {
		wpa_printf(MSG_DEBUG, "Unexpected IE (%u,%u) in coex report",
			   bc_ie->element_id, bc_ie->length);
		return;
	}
	if (len < IEEE80211_HDRLEN + 2 + 2 + bc_ie->length)
		return;
	data += 2 + bc_ie->length;

	wpa_printf(MSG_DEBUG, "20/40 BSS Coexistence Information field: 0x%x",
		   bc_ie->coex_param);
	if (bc_ie->coex_param & WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ) {
		hostapd_logger(hapd, mgmt->sa,
			       HOSTAPD_MODULE_IEEE80211,
			       HOSTAPD_LEVEL_DEBUG,
			       "20 MHz BSS width request bit is set in BSS coexistence information field");
		is_ht_allowed = 0;
	}

	if (bc_ie->coex_param & WLAN_20_40_BSS_COEX_40MHZ_INTOL) {
		hostapd_logger(hapd, mgmt->sa,
			       HOSTAPD_MODULE_IEEE80211,
			       HOSTAPD_LEVEL_DEBUG,
			       "40 MHz intolerant bit is set in BSS coexistence information field");
		is_ht_allowed = 0;
	}

	if (start + len - data >= 3 &&
	    data[0] == WLAN_EID_20_40_BSS_INTOLERANT && data[1] >= 1) {
		u8 ielen = data[1];

		if (ielen > start + len - data - 2)
			return;
		ic_report = (struct ieee80211_2040_intol_chan_report *) data;
		wpa_printf(MSG_DEBUG,
			   "20/40 BSS Intolerant Channel Report: Operating Class %u",
			   ic_report->op_class);

		/* Go through the channel report to find any BSS there in the
		 * affected channel range */
		for (i = 0; i < ielen - 1; i++) {
			u8 chan = ic_report->variable[i];

			if (is_40_allowed(iface, chan))
				continue;
			hostapd_logger(hapd, mgmt->sa,
				       HOSTAPD_MODULE_IEEE80211,
				       HOSTAPD_LEVEL_DEBUG,
				       "20_40_INTOLERANT channel %d reported",
				       chan);
			is_ht_allowed = 0;
		}
	}
	wpa_printf(MSG_DEBUG, "is_ht_allowed=%d num_sta_ht40_intolerant=%d",
		   is_ht_allowed, iface->num_sta_ht40_intolerant);

	if (!is_ht_allowed &&
	    (iface->drv_flags & WPA_DRIVER_FLAGS_HT_2040_COEX)) {
		if (iface->conf->secondary_channel) {
			hostapd_logger(hapd, mgmt->sa,
				       HOSTAPD_MODULE_IEEE80211,
				       HOSTAPD_LEVEL_INFO,
				       "Switching to 20 MHz operation");
			iface->conf->secondary_channel = 0;
			ieee802_11_set_beacons(iface);
		}
		if (!iface->num_sta_ht40_intolerant &&
		    iface->conf->obss_interval) {
			unsigned int delay_time;
			delay_time = OVERLAPPING_BSS_TRANS_DELAY_FACTOR *
				iface->conf->obss_interval;
			eloop_cancel_timeout(ap_ht2040_timeout, hapd->iface,
					     NULL);
			eloop_register_timeout(delay_time, 0, ap_ht2040_timeout,
					       hapd->iface, NULL);
			wpa_printf(MSG_DEBUG,
				   "Reschedule HT 20/40 timeout to occur in %u seconds",
				   delay_time);
		}
	}
}


u16 copy_sta_ht_capab(struct hostapd_data *hapd, struct sta_info *sta,
		      const u8 *ht_capab, size_t ht_capab_len)
{
	/*
	 * Disable HT caps for STAs associated to no-HT BSSes, or for stations
	 * that did not specify a valid WMM IE in the (Re)Association Request
	 * frame.
	 */
	if (!ht_capab ||
	    ht_capab_len < sizeof(struct ieee80211_ht_capabilities) ||
	    !(sta->flags & WLAN_STA_WMM) || hapd->conf->disable_11n) {
		sta->flags &= ~WLAN_STA_HT;
		os_free(sta->ht_capabilities);
		sta->ht_capabilities = NULL;
		return WLAN_STATUS_SUCCESS;
	}

	if (sta->ht_capabilities == NULL) {
		sta->ht_capabilities =
			os_zalloc(sizeof(struct ieee80211_ht_capabilities));
		if (sta->ht_capabilities == NULL)
			return WLAN_STATUS_UNSPECIFIED_FAILURE;
	}

	sta->flags |= WLAN_STA_HT;
	os_memcpy(sta->ht_capabilities, ht_capab,
		  sizeof(struct ieee80211_ht_capabilities));

	return WLAN_STATUS_SUCCESS;
}


void ht40_intolerant_add(struct hostapd_iface *iface, struct sta_info *sta)
{
	if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
		return;

	wpa_printf(MSG_INFO, "HT: Forty MHz Intolerant is set by STA " MACSTR
		   " in Association Request", MAC2STR(sta->addr));

	if (sta->ht40_intolerant_set)
		return;

	sta->ht40_intolerant_set = 1;
	iface->num_sta_ht40_intolerant++;
	eloop_cancel_timeout(ap_ht2040_timeout, iface, NULL);

	if (iface->conf->secondary_channel &&
	    (iface->drv_flags & WPA_DRIVER_FLAGS_HT_2040_COEX)) {
		iface->conf->secondary_channel = 0;
		ieee802_11_set_beacons(iface);
	}
}


void ht40_intolerant_remove(struct hostapd_iface *iface, struct sta_info *sta)
{
	if (!sta->ht40_intolerant_set)
		return;

	sta->ht40_intolerant_set = 0;
	iface->num_sta_ht40_intolerant--;

	if (iface->num_sta_ht40_intolerant == 0 &&
	    (iface->conf->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
	    (iface->drv_flags & WPA_DRIVER_FLAGS_HT_2040_COEX)) {
		unsigned int delay_time = OVERLAPPING_BSS_TRANS_DELAY_FACTOR *
			iface->conf->obss_interval;
		wpa_printf(MSG_DEBUG,
			   "HT: Start 20->40 MHz transition timer (%d seconds)",
			   delay_time);
		eloop_cancel_timeout(ap_ht2040_timeout, iface, NULL);
		eloop_register_timeout(delay_time, 0, ap_ht2040_timeout,
				       iface, NULL);
	}
}


static void update_sta_ht(struct hostapd_data *hapd, struct sta_info *sta)
{
	u16 ht_capab;

	ht_capab = le_to_host16(sta->ht_capabilities->ht_capabilities_info);
	wpa_printf(MSG_DEBUG, "HT: STA " MACSTR " HT Capabilities Info: "
		   "0x%04x", MAC2STR(sta->addr), ht_capab);
	if ((ht_capab & HT_CAP_INFO_GREEN_FIELD) == 0) {
		if (!sta->no_ht_gf_set) {
			sta->no_ht_gf_set = 1;
			hapd->iface->num_sta_ht_no_gf++;
		}
		wpa_printf(MSG_DEBUG, "%s STA " MACSTR " - no greenfield, num "
			   "of non-gf stations %d",
			   __func__, MAC2STR(sta->addr),
			   hapd->iface->num_sta_ht_no_gf);
	}
	if ((ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) == 0) {
		if (!sta->ht_20mhz_set) {
			sta->ht_20mhz_set = 1;
			hapd->iface->num_sta_ht_20mhz++;
		}
		wpa_printf(MSG_DEBUG, "%s STA " MACSTR " - 20 MHz HT, num of "
			   "20MHz HT STAs %d",
			   __func__, MAC2STR(sta->addr),
			   hapd->iface->num_sta_ht_20mhz);
	}

	if (ht_capab & HT_CAP_INFO_40MHZ_INTOLERANT)
		ht40_intolerant_add(hapd->iface, sta);
}


static void update_sta_no_ht(struct hostapd_data *hapd, struct sta_info *sta)
{
	if (!sta->no_ht_set) {
		sta->no_ht_set = 1;
		hapd->iface->num_sta_no_ht++;
	}
	if (hapd->iconf->ieee80211n) {
		wpa_printf(MSG_DEBUG, "%s STA " MACSTR " - no HT, num of "
			   "non-HT stations %d",
			   __func__, MAC2STR(sta->addr),
			   hapd->iface->num_sta_no_ht);
	}
}


void update_ht_state(struct hostapd_data *hapd, struct sta_info *sta)
{
	if ((sta->flags & WLAN_STA_HT) && sta->ht_capabilities)
		update_sta_ht(hapd, sta);
	else
		update_sta_no_ht(hapd, sta);

	if (hostapd_ht_operation_update(hapd->iface) > 0)
		ieee802_11_set_beacons(hapd->iface);
}


void hostapd_get_ht_capab(struct hostapd_data *hapd,
			  struct ieee80211_ht_capabilities *ht_cap,
			  struct ieee80211_ht_capabilities *neg_ht_cap)
{
	u16 cap;

	if (ht_cap == NULL)
		return;
	os_memcpy(neg_ht_cap, ht_cap, sizeof(*neg_ht_cap));
	cap = le_to_host16(neg_ht_cap->ht_capabilities_info);

	/*
	 * Mask out HT features we don't support, but don't overwrite
	 * non-symmetric features like STBC and SMPS. Just because
	 * we're not in dynamic SMPS mode the STA might still be.
	 */
	cap &= (hapd->iconf->ht_capab | HT_CAP_INFO_RX_STBC_MASK |
		HT_CAP_INFO_TX_STBC | HT_CAP_INFO_SMPS_MASK);

	/*
	 * STBC needs to be handled specially
	 * if we don't support RX STBC, mask out TX STBC in the STA's HT caps
	 * if we don't support TX STBC, mask out RX STBC in the STA's HT caps
	 */
	if (!(hapd->iconf->ht_capab & HT_CAP_INFO_RX_STBC_MASK))
		cap &= ~HT_CAP_INFO_TX_STBC;
	if (!(hapd->iconf->ht_capab & HT_CAP_INFO_TX_STBC))
		cap &= ~HT_CAP_INFO_RX_STBC_MASK;

	neg_ht_cap->ht_capabilities_info = host_to_le16(cap);
}


void ap_ht2040_timeout(void *eloop_data, void *user_data)
{
	struct hostapd_iface *iface = eloop_data;

	wpa_printf(MSG_INFO, "Switching to 40 MHz operation");

	iface->conf->secondary_channel = iface->secondary_ch;
	ieee802_11_set_beacons(iface);
}
