/*
 * hostapd / RM (Radio Management)
 * Copyright (c) 2015, Google, Inc
 *
 * 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 "common/ieee802_11_defs.h"
#include "common/ieee802_11_common.h"
#include "hostapd.h"
#include "ieee802_11.h"
#include "sta_info.h"
#include "ap_config.h"
#include "ap_drv_ops.h"

/* Common clients only look at the first 6 APs in the list anyway. */
#define NR_MAX_APS 6

/*
 * bssinfo is defined in 802.11-2012 Figure 8-216,
 * Table 8-114, and Figure 8-217.
 */
static u32 cap_to_bssinfo(u32 cap)
{
	u32 ap_reach = 2 << 0;  // Reachability unknown
	u32 security = 1 << 2;
	u32 key_scope = 0 << 3;
	u32 capabilities = 0;

	if (cap & (1 << 8)) capabilities |= (1 << 4);  // Spectrum Management
	capabilities |= (0 << 5);  // QoS
	if (cap & (1 << 11)) capabilities |= (1 << 6);  // APSD
	if (cap & (1 << 12)) capabilities |= (1 << 7);  // Radio Measurement
	if (cap & (1 << 14)) capabilities |= (1 << 8);  // Delayed Block Ack
	if (cap & (1 << 15)) capabilities |= (1 << 9);  // Immed Block Ack

	return ap_reach | security | key_scope | capabilities;
}

static void rm_send_neighbor_report(struct hostapd_data *hapd, const u8 *addr,
				    u8 dialog_token)
{
	#define ELEMSIZ sizeof(struct rrm_neighbor_report_element)
	u8 buf[sizeof(struct ieee80211_mgmt) + NR_MAX_APS * ELEMSIZ];
	struct ieee80211_mgmt *m = (struct ieee80211_mgmt *)buf;
	u8 *v = m->u.action.u.rm_action.variable;
	struct rrm_neighbor_report_element *elements =
		(struct rrm_neighbor_report_element *) v;
	int num_aps = 0;
	size_t len;

	/* TODO: if the neighbor request included a specific SSID,
	 * we need to compare with hapd->conf->ssid. If the SSID
	 * does not match, we should send back an action frame with
	 * some kind of refused or mismatch error code. */

	os_memset(&buf, 0, sizeof(buf));
	m->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
					WLAN_FC_STYPE_ACTION);
	os_memcpy(m->da, addr, ETH_ALEN);
	os_memcpy(m->sa, hapd->own_addr, ETH_ALEN);
	os_memcpy(m->bssid, hapd->own_addr, ETH_ALEN);
	m->u.action.category = WLAN_ACTION_RADIO_MEASUREMENT;
	m->u.action.u.rm_action.action = WLAN_RRM_NEIGHBOR_REPORT_RESPONSE;
	m->u.action.u.rm_action.dialog_token = dialog_token;

	if (hapd->conf->neighbor_ap_list_file) {
		FILE *f = fopen(hapd->conf->neighbor_ap_list_file, "r");
		char line[128];

		while (f && fgets(line, sizeof(line), f)) {
			char *start = line;
			char *tok, *save = NULL;
			const char *bssid = NULL;
			u32 cap = 0, bssinfo = 0;
			u8 channel = 0, phy_type = 0;
			struct rrm_neighbor_report_element *elem;

			if (num_aps >= NR_MAX_APS) {
				break;
			}

			while ((tok = strtok_r(start, "|", &save)) != NULL) {
				start = NULL;
				if (strncmp(tok, "bssid:", 6) == 0) {
					bssid = tok + 6;
				}
				if (strncmp(tok, "cap:", 4) == 0) {
					cap = strtol(tok + 4, NULL, 0);
				}
				if (strncmp(tok, "freq:", 5) == 0) {
					u32 freq = strtol(tok + 5, NULL, 0);
					ieee80211_freq_to_chan(freq, &channel);
				}
				if (strncmp(tok, "phy:", 4) == 0) {
					phy_type = (u8)strtol(tok + 4, NULL, 0);
				}
			}

			if (bssid == NULL || *bssid == '\0') {
				continue;
			}

			elem = &elements[num_aps];

			if (hwaddr_aton(bssid, elem->bssid) != 0) {
				continue;
			}
			elem->eid = WLAN_EID_NEIGHBOR_REPORT;
			elem->len = sizeof(*elem) - 2;
			bssinfo = cap_to_bssinfo(cap);
			WPA_PUT_LE32((u8 *)&elem->bssinfo, bssinfo);
			elem->op_class = 0;  // TODO: regulatory class.
			elem->channel = channel;
			elem->phy_type = phy_type;
			num_aps++;
		}
		if (f) {
			fclose(f);
		} else {
			hostapd_logger(hapd, m->da, HOSTAPD_MODULE_IEEE80211,
				HOSTAPD_LEVEL_NOTICE, "unable to open %s",
				hapd->conf->neighbor_ap_list_file);
		}
	}

	len = (u8 *)&elements[num_aps] - buf;
	hostapd_logger(hapd, m->da, HOSTAPD_MODULE_IEEE80211,
		HOSTAPD_LEVEL_NOTICE, "sending Neighbor List with %d APs",
		num_aps);
	if (hostapd_drv_send_mlme(hapd, m, len, 0) < 0)
		wpa_printf(MSG_WARNING, "rm_send_neighbor_report: send failed");
}


/*
 * Process a WLAN_ACTION_RADIO_MEASUREMENT frame.
 */
void hostapd_rm_action(struct hostapd_data *hapd,
		       const struct ieee80211_mgmt *mgmt, size_t len)
{
	int action_code;
	struct sta_info *sta = ap_get_sta(hapd, mgmt->sa);
	u8 dialog_token;

	/* Check that the request comes from a valid station. */
	if (!sta || !(sta->flags & WLAN_STA_ASSOC)) {
		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
			       HOSTAPD_LEVEL_NOTICE,
			       "rm action received is not from an associated "
			       "station");
		/* TODO: respond with action frame refused status code */
		return;
	}

	action_code = mgmt->u.action.u.rm_action.action;
	dialog_token = mgmt->u.action.u.wmm_action.dialog_token;
	switch (action_code) {
	case WLAN_RRM_NEIGHBOR_REPORT_REQUEST:
		rm_send_neighbor_report(hapd, mgmt->sa, dialog_token);
		return;
	}

	hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
		       HOSTAPD_LEVEL_INFO,
		       "hostapd_rm_action - unknown action code %d",
		       action_code);
}
