/*
 * 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_DEBUG, "sending Neighbor List with %d APs",
		num_aps);
	if (hostapd_drv_send_mlme(hapd, m, len, 0) < 0)
		wpa_printf(MSG_INFO, "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_DEBUG,
			       "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_DEBUG,
		       "hostapd_rm_action - unknown action code %d",
		       action_code);
}
