/*
 * wpa_supplicant - Radio Measurements
 * Copyright (c) 2003-2016, 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 "utils/common.h"
#include "utils/eloop.h"
#include "common/ieee802_11_common.h"
#include "wpa_supplicant_i.h"
#include "driver_i.h"
#include "bss.h"
#include "scan.h"
#include "p2p_supplicant.h"


static void wpas_rrm_neighbor_rep_timeout_handler(void *data, void *user_ctx)
{
	struct rrm_data *rrm = data;

	if (!rrm->notify_neighbor_rep) {
		wpa_printf(MSG_ERROR,
			   "RRM: Unexpected neighbor report timeout");
		return;
	}

	wpa_printf(MSG_DEBUG, "RRM: Notifying neighbor report - NONE");
	rrm->notify_neighbor_rep(rrm->neighbor_rep_cb_ctx, NULL);

	rrm->notify_neighbor_rep = NULL;
	rrm->neighbor_rep_cb_ctx = NULL;
}


/*
 * wpas_rrm_reset - Clear and reset all RRM data in wpa_supplicant
 * @wpa_s: Pointer to wpa_supplicant
 */
void wpas_rrm_reset(struct wpa_supplicant *wpa_s)
{
	wpa_s->rrm.rrm_used = 0;

	eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm,
			     NULL);
	if (wpa_s->rrm.notify_neighbor_rep)
		wpas_rrm_neighbor_rep_timeout_handler(&wpa_s->rrm, NULL);
	wpa_s->rrm.next_neighbor_rep_token = 1;
	wpas_clear_beacon_rep_data(wpa_s);
}


/*
 * wpas_rrm_process_neighbor_rep - Handle incoming neighbor report
 * @wpa_s: Pointer to wpa_supplicant
 * @report: Neighbor report buffer, prefixed by a 1-byte dialog token
 * @report_len: Length of neighbor report buffer
 */
void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s,
				   const u8 *report, size_t report_len)
{
	struct wpabuf *neighbor_rep;

	wpa_hexdump(MSG_DEBUG, "RRM: New Neighbor Report", report, report_len);
	if (report_len < 1)
		return;

	if (report[0] != wpa_s->rrm.next_neighbor_rep_token - 1) {
		wpa_printf(MSG_DEBUG,
			   "RRM: Discarding neighbor report with token %d (expected %d)",
			   report[0], wpa_s->rrm.next_neighbor_rep_token - 1);
		return;
	}

	eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm,
			     NULL);

	if (!wpa_s->rrm.notify_neighbor_rep) {
		wpa_msg(wpa_s, MSG_INFO, "RRM: Unexpected neighbor report");
		return;
	}

	/* skipping the first byte, which is only an id (dialog token) */
	neighbor_rep = wpabuf_alloc(report_len - 1);
	if (!neighbor_rep) {
		wpas_rrm_neighbor_rep_timeout_handler(&wpa_s->rrm, NULL);
		return;
	}
	wpabuf_put_data(neighbor_rep, report + 1, report_len - 1);
	wpa_dbg(wpa_s, MSG_DEBUG, "RRM: Notifying neighbor report (token = %d)",
		report[0]);
	wpa_s->rrm.notify_neighbor_rep(wpa_s->rrm.neighbor_rep_cb_ctx,
				       neighbor_rep);
	wpa_s->rrm.notify_neighbor_rep = NULL;
	wpa_s->rrm.neighbor_rep_cb_ctx = NULL;
}


#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS)
/* Workaround different, undefined for Windows, error codes used here */
#ifndef ENOTCONN
#define ENOTCONN -1
#endif
#ifndef EOPNOTSUPP
#define EOPNOTSUPP -1
#endif
#ifndef ECANCELED
#define ECANCELED -1
#endif
#endif

/* Measurement Request element + Location Subject + Maximum Age subelement */
#define MEASURE_REQUEST_LCI_LEN (3 + 1 + 4)
/* Measurement Request element + Location Civic Request */
#define MEASURE_REQUEST_CIVIC_LEN (3 + 5)


/**
 * wpas_rrm_send_neighbor_rep_request - Request a neighbor report from our AP
 * @wpa_s: Pointer to wpa_supplicant
 * @ssid: if not null, this is sent in the request. Otherwise, no SSID IE
 *	  is sent in the request.
 * @lci: if set, neighbor request will include LCI request
 * @civic: if set, neighbor request will include civic location request
 * @cb: Callback function to be called once the requested report arrives, or
 *	timed out after RRM_NEIGHBOR_REPORT_TIMEOUT seconds.
 *	In the former case, 'neighbor_rep' is a newly allocated wpabuf, and it's
 *	the requester's responsibility to free it.
 *	In the latter case NULL will be sent in 'neighbor_rep'.
 * @cb_ctx: Context value to send the callback function
 * Returns: 0 in case of success, negative error code otherwise
 *
 * In case there is a previous request which has not been answered yet, the
 * new request fails. The caller may retry after RRM_NEIGHBOR_REPORT_TIMEOUT.
 * Request must contain a callback function.
 */
int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s,
				       const struct wpa_ssid_value *ssid,
				       int lci, int civic,
				       void (*cb)(void *ctx,
						  struct wpabuf *neighbor_rep),
				       void *cb_ctx)
{
	struct wpabuf *buf;
	const u8 *rrm_ie;

	if (wpa_s->wpa_state != WPA_COMPLETED || wpa_s->current_ssid == NULL) {
		wpa_dbg(wpa_s, MSG_DEBUG, "RRM: No connection, no RRM.");
		return -ENOTCONN;
	}

	if (!wpa_s->rrm.rrm_used) {
		wpa_dbg(wpa_s, MSG_DEBUG, "RRM: No RRM in current connection.");
		return -EOPNOTSUPP;
	}

	rrm_ie = wpa_bss_get_ie(wpa_s->current_bss,
				WLAN_EID_RRM_ENABLED_CAPABILITIES);
	if (!rrm_ie || !(wpa_s->current_bss->caps & IEEE80211_CAP_RRM) ||
	    !(rrm_ie[2] & WLAN_RRM_CAPS_NEIGHBOR_REPORT)) {
		wpa_dbg(wpa_s, MSG_DEBUG,
			"RRM: No network support for Neighbor Report.");
		return -EOPNOTSUPP;
	}

	/* Refuse if there's a live request */
	if (wpa_s->rrm.notify_neighbor_rep) {
		wpa_dbg(wpa_s, MSG_DEBUG,
			"RRM: Currently handling previous Neighbor Report.");
		return -EBUSY;
	}

	/* 3 = action category + action code + dialog token */
	buf = wpabuf_alloc(3 + (ssid ? 2 + ssid->ssid_len : 0) +
			   (lci ? 2 + MEASURE_REQUEST_LCI_LEN : 0) +
			   (civic ? 2 + MEASURE_REQUEST_CIVIC_LEN : 0));
	if (buf == NULL) {
		wpa_dbg(wpa_s, MSG_DEBUG,
			"RRM: Failed to allocate Neighbor Report Request");
		return -ENOMEM;
	}

	wpa_dbg(wpa_s, MSG_DEBUG,
		"RRM: Neighbor report request (for %s), token=%d",
		(ssid ? wpa_ssid_txt(ssid->ssid, ssid->ssid_len) : ""),
		wpa_s->rrm.next_neighbor_rep_token);

	wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
	wpabuf_put_u8(buf, WLAN_RRM_NEIGHBOR_REPORT_REQUEST);
	wpabuf_put_u8(buf, wpa_s->rrm.next_neighbor_rep_token);
	if (ssid) {
		wpabuf_put_u8(buf, WLAN_EID_SSID);
		wpabuf_put_u8(buf, ssid->ssid_len);
		wpabuf_put_data(buf, ssid->ssid, ssid->ssid_len);
	}

	if (lci) {
		/* IEEE P802.11-REVmc/D5.0 9.4.2.21 */
		wpabuf_put_u8(buf, WLAN_EID_MEASURE_REQUEST);
		wpabuf_put_u8(buf, MEASURE_REQUEST_LCI_LEN);

		/*
		 * Measurement token; nonzero number that is unique among the
		 * Measurement Request elements in a particular frame.
		 */
		wpabuf_put_u8(buf, 1); /* Measurement Token */

		/*
		 * Parallel, Enable, Request, and Report bits are 0, Duration is
		 * reserved.
		 */
		wpabuf_put_u8(buf, 0); /* Measurement Request Mode */
		wpabuf_put_u8(buf, MEASURE_TYPE_LCI); /* Measurement Type */

		/* IEEE P802.11-REVmc/D5.0 9.4.2.21.10 - LCI request */
		/* Location Subject */
		wpabuf_put_u8(buf, LOCATION_SUBJECT_REMOTE);

		/* Optional Subelements */
		/*
		 * IEEE P802.11-REVmc/D5.0 Figure 9-170
		 * The Maximum Age subelement is required, otherwise the AP can
		 * send only data that was determined after receiving the
		 * request. Setting it here to unlimited age.
		 */
		wpabuf_put_u8(buf, LCI_REQ_SUBELEM_MAX_AGE);
		wpabuf_put_u8(buf, 2);
		wpabuf_put_le16(buf, 0xffff);
	}

	if (civic) {
		/* IEEE P802.11-REVmc/D5.0 9.4.2.21 */
		wpabuf_put_u8(buf, WLAN_EID_MEASURE_REQUEST);
		wpabuf_put_u8(buf, MEASURE_REQUEST_CIVIC_LEN);

		/*
		 * Measurement token; nonzero number that is unique among the
		 * Measurement Request elements in a particular frame.
		 */
		wpabuf_put_u8(buf, 2); /* Measurement Token */

		/*
		 * Parallel, Enable, Request, and Report bits are 0, Duration is
		 * reserved.
		 */
		wpabuf_put_u8(buf, 0); /* Measurement Request Mode */
		/* Measurement Type */
		wpabuf_put_u8(buf, MEASURE_TYPE_LOCATION_CIVIC);

		/* IEEE P802.11-REVmc/D5.0 9.4.2.21.14:
		 * Location Civic request */
		/* Location Subject */
		wpabuf_put_u8(buf, LOCATION_SUBJECT_REMOTE);
		wpabuf_put_u8(buf, 0); /* Civic Location Type: IETF RFC 4776 */
		/* Location Service Interval Units: Seconds */
		wpabuf_put_u8(buf, 0);
		/* Location Service Interval: 0 - Only one report is requested
		 */
		wpabuf_put_le16(buf, 0);
		/* No optional subelements */
	}

	wpa_s->rrm.next_neighbor_rep_token++;

	if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
				wpa_s->own_addr, wpa_s->bssid,
				wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
		wpa_dbg(wpa_s, MSG_DEBUG,
			"RRM: Failed to send Neighbor Report Request");
		wpabuf_free(buf);
		return -ECANCELED;
	}

	wpa_s->rrm.neighbor_rep_cb_ctx = cb_ctx;
	wpa_s->rrm.notify_neighbor_rep = cb;
	eloop_register_timeout(RRM_NEIGHBOR_REPORT_TIMEOUT, 0,
			       wpas_rrm_neighbor_rep_timeout_handler,
			       &wpa_s->rrm, NULL);

	wpabuf_free(buf);
	return 0;
}


static int wpas_rrm_report_elem(struct wpabuf **buf, u8 token, u8 mode, u8 type,
				const u8 *data, size_t data_len)
{
	if (wpabuf_resize(buf, 5 + data_len))
		return -1;

	wpabuf_put_u8(*buf, WLAN_EID_MEASURE_REPORT);
	wpabuf_put_u8(*buf, 3 + data_len);
	wpabuf_put_u8(*buf, token);
	wpabuf_put_u8(*buf, mode);
	wpabuf_put_u8(*buf, type);

	if (data_len)
		wpabuf_put_data(*buf, data, data_len);

	return 0;
}


static int
wpas_rrm_build_lci_report(struct wpa_supplicant *wpa_s,
			  const struct rrm_measurement_request_element *req,
			  struct wpabuf **buf)
{
	u8 subject;
	u16 max_age = 0;
	struct os_reltime t, diff;
	unsigned long diff_l;
	const u8 *subelem;
	const u8 *request = req->variable;
	size_t len = req->len - 3;

	if (len < 1)
		return -1;

	if (!wpa_s->lci)
		goto reject;

	subject = *request++;
	len--;

	wpa_printf(MSG_DEBUG, "Measurement request location subject=%u",
		   subject);

	if (subject != LOCATION_SUBJECT_REMOTE) {
		wpa_printf(MSG_INFO,
			   "Not building LCI report - bad location subject");
		return 0;
	}

	/* Subelements are formatted exactly like elements */
	wpa_hexdump(MSG_DEBUG, "LCI request subelements", request, len);
	subelem = get_ie(request, len, LCI_REQ_SUBELEM_MAX_AGE);
	if (subelem && subelem[1] == 2)
		max_age = WPA_GET_LE16(subelem + 2);

	if (os_get_reltime(&t))
		goto reject;

	os_reltime_sub(&t, &wpa_s->lci_time, &diff);
	/* LCI age is calculated in 10th of a second units. */
	diff_l = diff.sec * 10 + diff.usec / 100000;

	if (max_age != 0xffff && max_age < diff_l)
		goto reject;

	if (wpas_rrm_report_elem(buf, req->token,
				 MEASUREMENT_REPORT_MODE_ACCEPT, req->type,
				 wpabuf_head_u8(wpa_s->lci),
				 wpabuf_len(wpa_s->lci)) < 0) {
		wpa_printf(MSG_DEBUG, "Failed to add LCI report element");
		return -1;
	}

	return 0;

reject:
	if (!is_multicast_ether_addr(wpa_s->rrm.dst_addr) &&
	    wpas_rrm_report_elem(buf, req->token,
				 MEASUREMENT_REPORT_MODE_REJECT_INCAPABLE,
				 req->type, NULL, 0) < 0) {
		wpa_printf(MSG_DEBUG, "RRM: Failed to add report element");
		return -1;
	}

	return 0;
}


static void wpas_rrm_send_msr_report_mpdu(struct wpa_supplicant *wpa_s,
					  const u8 *data, size_t len)
{
	struct wpabuf *report = wpabuf_alloc(len + 3);

	if (!report)
		return;

	wpabuf_put_u8(report, WLAN_ACTION_RADIO_MEASUREMENT);
	wpabuf_put_u8(report, WLAN_RRM_RADIO_MEASUREMENT_REPORT);
	wpabuf_put_u8(report, wpa_s->rrm.token);

	wpabuf_put_data(report, data, len);

	if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
				wpa_s->own_addr, wpa_s->bssid,
				wpabuf_head(report), wpabuf_len(report), 0)) {
		wpa_printf(MSG_ERROR,
			   "RRM: Radio measurement report failed: Sending Action frame failed");
	}

	wpabuf_free(report);
}


static int wpas_rrm_beacon_rep_update_last_frame(u8 *pos, size_t len)
{
	struct rrm_measurement_report_element *msr_rep;
	u8 *end = pos + len;
	u8 *msr_rep_end;
	struct rrm_measurement_beacon_report *rep = NULL;
	u8 *subelem;

	/* Find the last beacon report element */
	while (end - pos >= (int) sizeof(*msr_rep)) {
		msr_rep = (struct rrm_measurement_report_element *) pos;
		msr_rep_end = pos + msr_rep->len + 2;

		if (msr_rep->eid != WLAN_EID_MEASURE_REPORT ||
		    msr_rep_end > end) {
			/* Should not happen. This indicates a bug. */
			wpa_printf(MSG_ERROR,
				   "RRM: non-measurement report element in measurement report frame");
			return -1;
		}

		if (msr_rep->type == MEASURE_TYPE_BEACON)
			rep = (struct rrm_measurement_beacon_report *)
				msr_rep->variable;

		pos += pos[1] + 2;
	}

	if (!rep)
		return 0;

	subelem = rep->variable;
	while (subelem + 2 < msr_rep_end &&
	       subelem[0] != WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION)
		subelem += 2 + subelem[1];

	if (subelem + 2 < msr_rep_end &&
	    subelem[0] == WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION &&
	    subelem[1] == 1 &&
	    subelem + BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN <= end)
		subelem[2] = 1;

	return 0;
}


static void wpas_rrm_send_msr_report(struct wpa_supplicant *wpa_s,
				     struct wpabuf *buf)
{
	int len = wpabuf_len(buf);
	u8 *pos = wpabuf_mhead_u8(buf), *next = pos;

#define MPDU_REPORT_LEN (int) (IEEE80211_MAX_MMPDU_SIZE - IEEE80211_HDRLEN - 3)

	while (len) {
		int send_len = (len > MPDU_REPORT_LEN) ? next - pos : len;

		if (send_len == len)
			wpas_rrm_beacon_rep_update_last_frame(pos, len);

		if (send_len == len ||
		    (send_len + next[1] + 2) > MPDU_REPORT_LEN) {
			wpas_rrm_send_msr_report_mpdu(wpa_s, pos, send_len);
			len -= send_len;
			pos = next;
		}

		if (len)
			next += next[1] + 2;
	}
#undef MPDU_REPORT_LEN
}


static int wpas_add_channel(u8 op_class, u8 chan, u8 num_primary_channels,
			    int *freqs)
{
	size_t i;

	for (i = 0; i < num_primary_channels; i++) {
		u8 primary_chan = chan - (2 * num_primary_channels - 2) + i * 4;

		freqs[i] = ieee80211_chan_to_freq(NULL, op_class, primary_chan);
		/* ieee80211_chan_to_freq() is not really meant for this
		 * conversion of 20 MHz primary channel numbers for wider VHT
		 * channels, so handle those as special cases here for now. */
		if (freqs[i] < 0 &&
		    (op_class == 128 || op_class == 129 || op_class == 130))
			freqs[i] = 5000 + 5 * primary_chan;
		if (freqs[i] < 0) {
			wpa_printf(MSG_DEBUG,
				   "Beacon Report: Invalid channel %u",
				   chan);
			return -1;
		}
	}

	return 0;
}


static int * wpas_add_channels(const struct oper_class_map *op,
			       struct hostapd_hw_modes *mode,
			       const u8 *channels, const u8 size)
{
	int *freqs, *next_freq;
	u8 num_primary_channels, i;
	u8 num_chans;

	num_chans = channels ? size :
		(op->max_chan - op->min_chan) / op->inc + 1;

	if (op->bw == BW80 || op->bw == BW80P80)
		num_primary_channels = 4;
	else if (op->bw == BW160)
		num_primary_channels = 8;
	else
		num_primary_channels = 1;

	/* one extra place for the zero-terminator */
	freqs = os_calloc(num_chans * num_primary_channels + 1, sizeof(*freqs));
	if (!freqs) {
		wpa_printf(MSG_ERROR,
			   "Beacon Report: Failed to allocate freqs array");
		return NULL;
	}

	next_freq = freqs;
	for  (i = 0; i < num_chans; i++) {
		u8 chan = channels ? channels[i] : op->min_chan + i * op->inc;
		enum chan_allowed res = verify_channel(mode, op->op_class, chan,
						       op->bw);

		if (res == NOT_ALLOWED)
			continue;

		if (wpas_add_channel(op->op_class, chan, num_primary_channels,
				     next_freq) < 0) {
			os_free(freqs);
			return NULL;
		}

		next_freq += num_primary_channels;
	}

	if (!freqs[0]) {
		os_free(freqs);
		return NULL;
	}

	return freqs;
}


static int * wpas_op_class_freqs(const struct oper_class_map *op,
				 struct hostapd_hw_modes *mode)
{
	u8 channels_80mhz_5ghz[] = { 42, 58, 106, 122, 138, 155, 171 };
	u8 channels_160mhz_5ghz[] = { 50, 114, 163 };
	u8 channels_80mhz_6ghz[] = { 7, 23, 39, 55, 71, 87, 103, 119, 135, 151,
				     167, 183, 199, 215 };
	u8 channels_160mhz_6ghz[] = { 15, 47, 79, 111, 143, 175, 207 };
	const u8 *channels = NULL;
	size_t num_chan = 0;
	bool is_6ghz = is_6ghz_op_class(op->op_class);

	/*
	 * When adding all channels in the operating class, 80 + 80 MHz
	 * operating classes are like 80 MHz channels because we add all valid
	 * channels anyway.
	 */
	if (op->bw == BW80 || op->bw == BW80P80) {
		channels = is_6ghz ? channels_80mhz_6ghz : channels_80mhz_5ghz;
		num_chan = is_6ghz ? ARRAY_SIZE(channels_80mhz_6ghz) :
			ARRAY_SIZE(channels_80mhz_5ghz);
	} else if (op->bw == BW160) {
		channels = is_6ghz ? channels_160mhz_6ghz :
			channels_160mhz_5ghz;
		num_chan =  is_6ghz ? ARRAY_SIZE(channels_160mhz_6ghz) :
			ARRAY_SIZE(channels_160mhz_5ghz);
	}

	return wpas_add_channels(op, mode, channels, num_chan);
}


static int * wpas_channel_report_freqs(struct wpa_supplicant *wpa_s,
				       const char *country, const u8 *subelems,
				       size_t len)
{
	int *freqs = NULL, *new_freqs;
	const u8 *end = subelems + len;

	while (end - subelems > 2) {
		const struct oper_class_map *op;
		const u8 *ap_chan_elem, *pos;
		u8 left;
		struct hostapd_hw_modes *mode;

		ap_chan_elem = get_ie(subelems, end - subelems,
				      WLAN_BEACON_REQUEST_SUBELEM_AP_CHANNEL);
		if (!ap_chan_elem)
			break;
		pos = ap_chan_elem + 2;
		left = ap_chan_elem[1];
		if (left < 1)
			break;
		subelems = ap_chan_elem + 2 + left;

		op = get_oper_class(country, *pos);
		if (!op) {
			wpa_printf(MSG_DEBUG,
				   "Beacon request: unknown operating class in AP Channel Report subelement %u",
				   *pos);
			goto out;
		}
		pos++;
		left--;

		mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op->mode,
				is_6ghz_op_class(op->op_class));
		if (!mode)
			continue;

		/*
		 * For 80 + 80 MHz operating classes, this AP Channel Report
		 * element should be followed by another element specifying
		 * the second 80 MHz channel. For now just add this 80 MHz
		 * channel, the second 80 MHz channel will be added when the
		 * next element is parsed.
		 * TODO: Verify that this AP Channel Report element is followed
		 * by a corresponding AP Channel Report element as specified in
		 * IEEE Std 802.11-2016, 11.11.9.1.
		 */
		new_freqs = wpas_add_channels(op, mode, pos, left);
		if (new_freqs)
			int_array_concat(&freqs, new_freqs);

		os_free(new_freqs);
	}

	return freqs;
out:
	os_free(freqs);
	return NULL;
}


static int * wpas_beacon_request_freqs(struct wpa_supplicant *wpa_s,
				       u8 op_class, u8 chan,
				       const u8 *subelems, size_t len)
{
	int *freqs = NULL, *ext_freqs = NULL;
	struct hostapd_hw_modes *mode;
	const char *country = NULL;
	const struct oper_class_map *op;
	const u8 *elem;

	if (!wpa_s->current_bss)
		return NULL;
	elem = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_COUNTRY);
	if (elem && elem[1] >= 2)
		country = (const char *) (elem + 2);

	op = get_oper_class(country, op_class);
	if (!op) {
		wpa_printf(MSG_DEBUG,
			   "Beacon request: invalid operating class %d",
			   op_class);
		return NULL;
	}

	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op->mode,
			is_6ghz_op_class(op->op_class));
	if (!mode)
		return NULL;

	switch (chan) {
	case 0:
		freqs = wpas_op_class_freqs(op, mode);
		if (!freqs)
			return NULL;
		break;
	case 255:
		/* freqs will be added from AP channel subelements */
		break;
	default:
		freqs = wpas_add_channels(op, mode, &chan, 1);
		if (!freqs)
			return NULL;
		break;
	}

	ext_freqs = wpas_channel_report_freqs(wpa_s, country, subelems, len);
	if (ext_freqs) {
		int_array_concat(&freqs, ext_freqs);
		os_free(ext_freqs);
		int_array_sort_unique(freqs);
	}

	return freqs;
}


int wpas_get_op_chan_phy(int freq, const u8 *ies, size_t ies_len,
			 u8 *op_class, u8 *chan, u8 *phy_type)
{
	const u8 *ie;
	int sec_chan = 0, vht = 0;
	struct ieee80211_ht_operation *ht_oper = NULL;
	struct ieee80211_vht_operation *vht_oper = NULL;
	u8 seg0, seg1;

	ie = get_ie(ies, ies_len, WLAN_EID_HT_OPERATION);
	if (ie && ie[1] >= sizeof(struct ieee80211_ht_operation)) {
		u8 sec_chan_offset;

		ht_oper = (struct ieee80211_ht_operation *) (ie + 2);
		sec_chan_offset = ht_oper->ht_param &
			HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
		if (sec_chan_offset == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE)
			sec_chan = 1;
		else if (sec_chan_offset ==
			 HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW)
			sec_chan = -1;
	}

	ie = get_ie(ies, ies_len, WLAN_EID_VHT_OPERATION);
	if (ie && ie[1] >= sizeof(struct ieee80211_vht_operation)) {
		vht_oper = (struct ieee80211_vht_operation *) (ie + 2);

		switch (vht_oper->vht_op_info_chwidth) {
		case CHANWIDTH_80MHZ:
			seg0 = vht_oper->vht_op_info_chan_center_freq_seg0_idx;
			seg1 = vht_oper->vht_op_info_chan_center_freq_seg1_idx;
			if (seg1 && abs(seg1 - seg0) == 8)
				vht = CONF_OPER_CHWIDTH_160MHZ;
			else if (seg1)
				vht = CONF_OPER_CHWIDTH_80P80MHZ;
			else
				vht = CONF_OPER_CHWIDTH_80MHZ;
			break;
		case CHANWIDTH_160MHZ:
			vht = CONF_OPER_CHWIDTH_160MHZ;
			break;
		case CHANWIDTH_80P80MHZ:
			vht = CONF_OPER_CHWIDTH_80P80MHZ;
			break;
		default:
			vht = CONF_OPER_CHWIDTH_USE_HT;
			break;
		}
	}

	if (ieee80211_freq_to_channel_ext(freq, sec_chan, vht, op_class,
					  chan) == NUM_HOSTAPD_MODES) {
		wpa_printf(MSG_DEBUG,
			   "Cannot determine operating class and channel");
		return -1;
	}

	*phy_type = ieee80211_get_phy_type(freq, ht_oper != NULL,
					   vht_oper != NULL);
	if (*phy_type == PHY_TYPE_UNSPECIFIED) {
		wpa_printf(MSG_DEBUG, "Cannot determine phy type");
		return -1;
	}

	return 0;
}


static int wpas_beacon_rep_add_frame_body(struct bitfield *eids,
					  enum beacon_report_detail detail,
					  struct wpa_bss *bss, u8 *buf,
					  size_t buf_len, const u8 **ies_buf,
					  size_t *ie_len, int add_fixed)
{
	const u8 *ies = *ies_buf;
	size_t ies_len = *ie_len;
	u8 *pos = buf;
	int rem_len;

	rem_len = 255 - sizeof(struct rrm_measurement_beacon_report) -
		sizeof(struct rrm_measurement_report_element) - 2 -
		REPORTED_FRAME_BODY_SUBELEM_LEN;

	if (detail > BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS) {
		wpa_printf(MSG_DEBUG,
			   "Beacon Request: Invalid reporting detail: %d",
			   detail);
		return -1;
	}

	if (detail == BEACON_REPORT_DETAIL_NONE)
		return 0;

	/*
	 * Minimal frame body subelement size: EID(1) + length(1) + TSF(8) +
	 * beacon interval(2) + capabilities(2) = 14 bytes
	 */
	if (add_fixed && buf_len < 14)
		return -1;

	*pos++ = WLAN_BEACON_REPORT_SUBELEM_FRAME_BODY;
	/* The length will be filled later */
	pos++;

	if (add_fixed) {
		WPA_PUT_LE64(pos, bss->tsf);
		pos += sizeof(bss->tsf);
		WPA_PUT_LE16(pos, bss->beacon_int);
		pos += 2;
		WPA_PUT_LE16(pos, bss->caps);
		pos += 2;
	}

	rem_len -= pos - buf;

	/*
	 * According to IEEE Std 802.11-2016, 9.4.2.22.7, if the reported frame
	 * body subelement causes the element to exceed the maximum element
	 * size, the subelement is truncated so that the last IE is a complete
	 * IE. So even when required to report all IEs, add elements one after
	 * the other and stop once there is no more room in the measurement
	 * element.
	 */
	while (ies_len > 2 && 2U + ies[1] <= ies_len && rem_len > 0) {
		if (detail == BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS ||
		    (eids && bitfield_is_set(eids, ies[0]))) {
			u8 elen = ies[1];

			if (2 + elen > buf + buf_len - pos ||
			    2 + elen > rem_len)
				break;

			*pos++ = ies[0];
			*pos++ = elen;
			os_memcpy(pos, ies + 2, elen);
			pos += elen;
			rem_len -= 2 + elen;
		}

		ies_len -= 2 + ies[1];
		ies += 2 + ies[1];
	}

	*ie_len = ies_len;
	*ies_buf = ies;

	/* Now the length is known */
	buf[1] = pos - buf - 2;
	return pos - buf;
}


static int wpas_add_beacon_rep_elem(struct beacon_rep_data *data,
				    struct wpa_bss *bss,
				    struct wpabuf **wpa_buf,
				    struct rrm_measurement_beacon_report *rep,
				    const u8 **ie, size_t *ie_len, u8 idx)
{
	int ret;
	u8 *buf, *pos;
	u32 subelems_len = REPORTED_FRAME_BODY_SUBELEM_LEN +
		(data->last_indication ?
		 BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN : 0);

	/* Maximum element length: Beacon Report element + Reported Frame Body
	 * subelement + all IEs of the reported Beacon frame + Reported Frame
	 * Body Fragment ID subelement */
	buf = os_malloc(sizeof(*rep) + 14 + *ie_len + subelems_len);
	if (!buf)
		return -1;

	os_memcpy(buf, rep, sizeof(*rep));

	ret = wpas_beacon_rep_add_frame_body(data->eids, data->report_detail,
					     bss, buf + sizeof(*rep),
					     14 + *ie_len, ie, ie_len,
					     idx == 0);
	if (ret < 0)
		goto out;

	pos = buf + ret + sizeof(*rep);
	pos[0] = WLAN_BEACON_REPORT_SUBELEM_FRAME_BODY_FRAGMENT_ID;
	pos[1] = 2;

	/*
	 * Only one Beacon Report Measurement is supported at a time, so
	 * the Beacon Report ID can always be set to 1.
	 */
	pos[2] = 1;

	/* Fragment ID Number (bits 0..6) and More Frame Body Fragments (bit 7)
 */
	pos[3] = idx;
	if (data->report_detail != BEACON_REPORT_DETAIL_NONE && *ie_len)
		pos[3] |= REPORTED_FRAME_BODY_MORE_FRAGMENTS;
	else
		pos[3] &= ~REPORTED_FRAME_BODY_MORE_FRAGMENTS;

	pos += REPORTED_FRAME_BODY_SUBELEM_LEN;

	if (data->last_indication) {
		pos[0] = WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION;
		pos[1] = 1;

		/* This field will be updated later if this is the last frame */
		pos[2] = 0;
	}

	ret = wpas_rrm_report_elem(wpa_buf, data->token,
				   MEASUREMENT_REPORT_MODE_ACCEPT,
				   MEASURE_TYPE_BEACON, buf,
				   ret + sizeof(*rep) + subelems_len);
out:
	os_free(buf);
	return ret;
}


static int wpas_add_beacon_rep(struct wpa_supplicant *wpa_s,
			       struct wpabuf **wpa_buf, struct wpa_bss *bss,
			       u64 start, u64 parent_tsf)
{
	struct beacon_rep_data *data = &wpa_s->beacon_rep_data;
	const u8 *ies = wpa_bss_ie_ptr(bss);
	const u8 *pos = ies;
	size_t ies_len = bss->ie_len ? bss->ie_len : bss->beacon_ie_len;
	struct rrm_measurement_beacon_report rep;
	u8 idx = 0;

	if (os_memcmp(data->bssid, broadcast_ether_addr, ETH_ALEN) != 0 &&
	    os_memcmp(data->bssid, bss->bssid, ETH_ALEN) != 0)
		return 0;

	if (data->ssid_len &&
	    (data->ssid_len != bss->ssid_len ||
	     os_memcmp(data->ssid, bss->ssid, bss->ssid_len) != 0))
		return 0;

	if (wpas_get_op_chan_phy(bss->freq, ies, ies_len, &rep.op_class,
				 &rep.channel, &rep.report_info) < 0)
		return 0;

	rep.start_time = host_to_le64(start);
	rep.duration = host_to_le16(data->scan_params.duration);
	rep.rcpi = rssi_to_rcpi(bss->level);
	rep.rsni = 255; /* 255 indicates that RSNI is not available */
	os_memcpy(rep.bssid, bss->bssid, ETH_ALEN);
	rep.antenna_id = 0; /* unknown */
	rep.parent_tsf = host_to_le32(parent_tsf);

	do {
		int ret;

		ret = wpas_add_beacon_rep_elem(data, bss, wpa_buf, &rep,
					       &pos, &ies_len, idx++);
		if (ret)
			return ret;
	} while (data->report_detail != BEACON_REPORT_DETAIL_NONE &&
		 ies_len >= 2);

	return 0;
}


static int wpas_beacon_rep_no_results(struct wpa_supplicant *wpa_s,
				      struct wpabuf **buf)
{
	return wpas_rrm_report_elem(buf, wpa_s->beacon_rep_data.token,
				    MEASUREMENT_REPORT_MODE_ACCEPT,
				    MEASURE_TYPE_BEACON, NULL, 0);
}


static void wpas_beacon_rep_table(struct wpa_supplicant *wpa_s,
				  struct wpabuf **buf)
{
	size_t i;

	for (i = 0; i < wpa_s->last_scan_res_used; i++) {
		if (wpas_add_beacon_rep(wpa_s, buf, wpa_s->last_scan_res[i],
					0, 0) < 0)
			break;
	}

	if (!(*buf))
		wpas_beacon_rep_no_results(wpa_s, buf);

	wpa_hexdump_buf(MSG_DEBUG, "RRM: Radio Measurement report", *buf);
}


void wpas_rrm_refuse_request(struct wpa_supplicant *wpa_s)
{
	if (!is_multicast_ether_addr(wpa_s->rrm.dst_addr)) {
		struct wpabuf *buf = NULL;

		if (wpas_rrm_report_elem(&buf, wpa_s->beacon_rep_data.token,
					 MEASUREMENT_REPORT_MODE_REJECT_REFUSED,
					 MEASURE_TYPE_BEACON, NULL, 0)) {
			wpa_printf(MSG_ERROR, "RRM: Memory allocation failed");
			wpabuf_free(buf);
			return;
		}

		wpas_rrm_send_msr_report(wpa_s, buf);
		wpabuf_free(buf);
	}

	wpas_clear_beacon_rep_data(wpa_s);
}


static void wpas_rrm_scan_timeout(void *eloop_ctx, void *timeout_ctx)
{
	struct wpa_supplicant *wpa_s = eloop_ctx;
	struct wpa_driver_scan_params *params =
		&wpa_s->beacon_rep_data.scan_params;
	u16 prev_duration = params->duration;

	if (!wpa_s->current_bss)
		return;

	if (!(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_SUPPORT_SET_SCAN_DWELL) &&
	    params->duration) {
		wpa_printf(MSG_DEBUG,
			   "RRM: Cannot set scan duration due to missing driver support");
		params->duration = 0;
	}
	os_get_reltime(&wpa_s->beacon_rep_scan);
	if (wpa_s->scanning || wpas_p2p_in_progress(wpa_s) ||
	    wpa_supplicant_trigger_scan(wpa_s, params))
		wpas_rrm_refuse_request(wpa_s);
	params->duration = prev_duration;
}


static int wpas_rm_handle_beacon_req_subelem(struct wpa_supplicant *wpa_s,
					     struct beacon_rep_data *data,
					     u8 sid, u8 slen, const u8 *subelem)
{
	u8 report_info, i;

	switch (sid) {
	case WLAN_BEACON_REQUEST_SUBELEM_SSID:
		if (!slen) {
			wpa_printf(MSG_DEBUG,
				   "SSID subelement with zero length - wildcard SSID");
			break;
		}

		if (slen > SSID_MAX_LEN) {
			wpa_printf(MSG_DEBUG,
				   "Invalid SSID subelement length: %u", slen);
			return -1;
		}

		data->ssid_len = slen;
		os_memcpy(data->ssid, subelem, data->ssid_len);
		break;
	case WLAN_BEACON_REQUEST_SUBELEM_INFO:
		if (slen != 2) {
			wpa_printf(MSG_DEBUG,
				   "Invalid reporting information subelement length: %u",
				   slen);
			return -1;
		}

		report_info = subelem[0];
		if (report_info != 0) {
			wpa_printf(MSG_DEBUG,
				   "reporting information=%u is not supported",
				   report_info);
			return 0;
		}
		break;
	case WLAN_BEACON_REQUEST_SUBELEM_DETAIL:
		if (slen != 1) {
			wpa_printf(MSG_DEBUG,
				   "Invalid reporting detail subelement length: %u",
				   slen);
			return -1;
		}

		data->report_detail = subelem[0];
		if (data->report_detail >
		    BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS) {
			wpa_printf(MSG_DEBUG, "Invalid reporting detail: %u",
				   subelem[0]);
			return -1;
		}

		break;
	case WLAN_BEACON_REQUEST_SUBELEM_REQUEST:
		if (data->report_detail !=
		    BEACON_REPORT_DETAIL_REQUESTED_ONLY) {
			wpa_printf(MSG_DEBUG,
				   "Beacon request: request subelement is present but report detail is %u",
				   data->report_detail);
			return -1;
		}

		if (!slen) {
			wpa_printf(MSG_DEBUG,
				   "Invalid request subelement length: %u",
				   slen);
			return -1;
		}

		if (data->eids) {
			wpa_printf(MSG_DEBUG,
				   "Beacon Request: Request subelement appears more than once");
			return -1;
		}

		data->eids = bitfield_alloc(255);
		if (!data->eids) {
			wpa_printf(MSG_DEBUG, "Failed to allocate EIDs bitmap");
			return -1;
		}

		for (i = 0; i < slen; i++)
			bitfield_set(data->eids, subelem[i]);
		break;
	case WLAN_BEACON_REQUEST_SUBELEM_AP_CHANNEL:
		/* Skip - it will be processed when freqs are added */
		break;
	case WLAN_BEACON_REQUEST_SUBELEM_LAST_INDICATION:
		if (slen != 1) {
			wpa_printf(MSG_DEBUG,
				   "Beacon request: Invalid last indication request subelement length: %u",
				   slen);
			return -1;
		}

		data->last_indication = subelem[0];
		break;
	default:
		wpa_printf(MSG_DEBUG,
			   "Beacon request: Unknown subelement id %u", sid);
		break;
	}

	return 1;
}


/**
 * Returns 0 if the next element can be processed, 1 if some operation was
 * triggered, and -1 if processing failed (i.e., the element is in invalid
 * format or an internal error occurred).
 */
static int
wpas_rm_handle_beacon_req(struct wpa_supplicant *wpa_s,
			  u8 elem_token, int duration_mandatory,
			  const struct rrm_measurement_beacon_request *req,
			  size_t len, struct wpabuf **buf)
{
	struct beacon_rep_data *data = &wpa_s->beacon_rep_data;
	struct wpa_driver_scan_params *params = &data->scan_params;
	const u8 *subelems;
	size_t elems_len;
	u16 rand_interval;
	u32 interval_usec;
	u32 _rand;
	int ret = 0, res;
	u8 reject_mode;

	if (len < sizeof(*req))
		return -1;

	if (req->mode != BEACON_REPORT_MODE_PASSIVE &&
	    req->mode != BEACON_REPORT_MODE_ACTIVE &&
	    req->mode != BEACON_REPORT_MODE_TABLE)
		return 0;

	subelems = req->variable;
	elems_len = len - sizeof(*req);
	rand_interval = le_to_host16(req->rand_interval);

	os_free(params->freqs);
	os_memset(params, 0, sizeof(*params));

	data->token = elem_token;

	/* default reporting detail is all fixed length fields and all
	 * elements */
	data->report_detail = BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS;
	os_memcpy(data->bssid, req->bssid, ETH_ALEN);

	while (elems_len >= 2) {
		if (subelems[1] > elems_len - 2) {
			wpa_printf(MSG_DEBUG,
				   "Beacon Request: Truncated subelement");
			ret = -1;
			goto out;
		}

		res = wpas_rm_handle_beacon_req_subelem(
			wpa_s, data, subelems[0], subelems[1], &subelems[2]);
		if (res < 0) {
			ret = res;
			goto out;
		} else if (!res) {
			reject_mode = MEASUREMENT_REPORT_MODE_REJECT_INCAPABLE;
			goto out_reject;
		}

		elems_len -= 2 + subelems[1];
		subelems += 2 + subelems[1];
	}

	if (req->mode == BEACON_REPORT_MODE_TABLE) {
		wpas_beacon_rep_table(wpa_s, buf);
		goto out;
	}

	params->freqs = wpas_beacon_request_freqs(wpa_s, req->oper_class,
						  req->channel, req->variable,
						  len - sizeof(*req));
	if (!params->freqs) {
		wpa_printf(MSG_DEBUG, "Beacon request: No valid channels");
		reject_mode = MEASUREMENT_REPORT_MODE_REJECT_REFUSED;
		goto out_reject;
	}

	params->duration = le_to_host16(req->duration);
	params->duration_mandatory = duration_mandatory;
	if (!params->duration) {
		wpa_printf(MSG_DEBUG, "Beacon request: Duration is 0");
		ret = -1;
		goto out;
	}

	params->only_new_results = 1;

	if (req->mode == BEACON_REPORT_MODE_ACTIVE) {
		params->ssids[params->num_ssids].ssid = data->ssid;
		params->ssids[params->num_ssids++].ssid_len = data->ssid_len;
	}

	if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0)
		_rand = os_random();
	interval_usec = (_rand % (rand_interval + 1)) * 1024;
	eloop_register_timeout(0, interval_usec, wpas_rrm_scan_timeout, wpa_s,
			       NULL);
	return 1;
out_reject:
	if (!is_multicast_ether_addr(wpa_s->rrm.dst_addr) &&
	    wpas_rrm_report_elem(buf, elem_token, reject_mode,
				 MEASURE_TYPE_BEACON, NULL, 0) < 0) {
		wpa_printf(MSG_DEBUG, "RRM: Failed to add report element");
		ret = -1;
	}
out:
	wpas_clear_beacon_rep_data(wpa_s);
	return ret;
}


static int
wpas_rrm_handle_msr_req_element(
	struct wpa_supplicant *wpa_s,
	const struct rrm_measurement_request_element *req,
	struct wpabuf **buf)
{
	int duration_mandatory;

	wpa_printf(MSG_DEBUG, "Measurement request type %d token %d",
		   req->type, req->token);

	if (req->mode & MEASUREMENT_REQUEST_MODE_ENABLE) {
		/* Enable bit is not supported for now */
		wpa_printf(MSG_DEBUG, "RRM: Enable bit not supported, ignore");
		return 0;
	}

	if ((req->mode & MEASUREMENT_REQUEST_MODE_PARALLEL) &&
	    req->type > MEASURE_TYPE_RPI_HIST) {
		/* Parallel measurements are not supported for now */
		wpa_printf(MSG_DEBUG,
			   "RRM: Parallel measurements are not supported, reject");
		goto reject;
	}

	duration_mandatory =
		!!(req->mode & MEASUREMENT_REQUEST_MODE_DURATION_MANDATORY);

	switch (req->type) {
	case MEASURE_TYPE_LCI:
		return wpas_rrm_build_lci_report(wpa_s, req, buf);
	case MEASURE_TYPE_BEACON:
		if (duration_mandatory &&
		    !(wpa_s->drv_rrm_flags &
		      WPA_DRIVER_FLAGS_SUPPORT_SET_SCAN_DWELL)) {
			wpa_printf(MSG_DEBUG,
				   "RRM: Driver does not support dwell time configuration - reject beacon report with mandatory duration");
			goto reject;
		}
		return wpas_rm_handle_beacon_req(wpa_s, req->token,
						 duration_mandatory,
						 (const void *) req->variable,
						 req->len - 3, buf);
	default:
		wpa_printf(MSG_INFO,
			   "RRM: Unsupported radio measurement type %u",
			   req->type);
		break;
	}

reject:
	if (!is_multicast_ether_addr(wpa_s->rrm.dst_addr) &&
	    wpas_rrm_report_elem(buf, req->token,
				 MEASUREMENT_REPORT_MODE_REJECT_INCAPABLE,
				 req->type, NULL, 0) < 0) {
		wpa_printf(MSG_DEBUG, "RRM: Failed to add report element");
		return -1;
	}

	return 0;
}


static struct wpabuf *
wpas_rrm_process_msr_req_elems(struct wpa_supplicant *wpa_s, const u8 *pos,
			       size_t len)
{
	struct wpabuf *buf = NULL;

	while (len) {
		const struct rrm_measurement_request_element *req;
		int res;

		if (len < 2) {
			wpa_printf(MSG_DEBUG, "RRM: Truncated element");
			goto out;
		}

		req = (const struct rrm_measurement_request_element *) pos;
		if (req->eid != WLAN_EID_MEASURE_REQUEST) {
			wpa_printf(MSG_DEBUG,
				   "RRM: Expected Measurement Request element, but EID is %u",
				   req->eid);
			goto out;
		}

		if (req->len < 3) {
			wpa_printf(MSG_DEBUG, "RRM: Element length too short");
			goto out;
		}

		if (req->len > len - 2) {
			wpa_printf(MSG_DEBUG, "RRM: Element length too long");
			goto out;
		}

		res = wpas_rrm_handle_msr_req_element(wpa_s, req, &buf);
		if (res < 0)
			goto out;

		pos += req->len + 2;
		len -= req->len + 2;
	}

	return buf;

out:
	wpabuf_free(buf);
	return NULL;
}


void wpas_rrm_handle_radio_measurement_request(struct wpa_supplicant *wpa_s,
					       const u8 *src, const u8 *dst,
					       const u8 *frame, size_t len)
{
	struct wpabuf *report;

	if (wpa_s->wpa_state != WPA_COMPLETED) {
		wpa_printf(MSG_INFO,
			   "RRM: Ignoring radio measurement request: Not associated");
		return;
	}

	if (!wpa_s->rrm.rrm_used) {
		wpa_printf(MSG_INFO,
			   "RRM: Ignoring radio measurement request: Not RRM network");
		return;
	}

	if (len < 3) {
		wpa_printf(MSG_INFO,
			   "RRM: Ignoring too short radio measurement request");
		return;
	}

	wpa_s->rrm.token = *frame;
	os_memcpy(wpa_s->rrm.dst_addr, dst, ETH_ALEN);

	/* Number of repetitions is not supported */

	report = wpas_rrm_process_msr_req_elems(wpa_s, frame + 3, len - 3);
	if (!report)
		return;

	wpas_rrm_send_msr_report(wpa_s, report);
	wpabuf_free(report);
}


void wpas_rrm_handle_link_measurement_request(struct wpa_supplicant *wpa_s,
					      const u8 *src,
					      const u8 *frame, size_t len,
					      int rssi)
{
	struct wpabuf *buf;
	const struct rrm_link_measurement_request *req;
	struct rrm_link_measurement_report report;

	if (wpa_s->wpa_state != WPA_COMPLETED) {
		wpa_printf(MSG_INFO,
			   "RRM: Ignoring link measurement request. Not associated");
		return;
	}

	if (!wpa_s->rrm.rrm_used) {
		wpa_printf(MSG_INFO,
			   "RRM: Ignoring link measurement request. Not RRM network");
		return;
	}

	if (!(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION)) {
		wpa_printf(MSG_INFO,
			   "RRM: Measurement report failed. TX power insertion not supported");
		return;
	}

	req = (const struct rrm_link_measurement_request *) frame;
	if (len < sizeof(*req)) {
		wpa_printf(MSG_INFO,
			   "RRM: Link measurement report failed. Request too short");
		return;
	}

	os_memset(&report, 0, sizeof(report));
	report.dialog_token = req->dialog_token;
	report.tpc.eid = WLAN_EID_TPC_REPORT;
	report.tpc.len = 2;
	/* Note: The driver is expected to update report.tpc.tx_power and
	 * report.tpc.link_margin subfields when sending out this frame.
	 * Similarly, the driver would need to update report.rx_ant_id and
	 * report.tx_ant_id subfields. */
	report.rsni = 255; /* 255 indicates that RSNI is not available */
	report.rcpi = rssi_to_rcpi(rssi);

	/* action_category + action_code */
	buf = wpabuf_alloc(2 + sizeof(report));
	if (buf == NULL) {
		wpa_printf(MSG_ERROR,
			   "RRM: Link measurement report failed. Buffer allocation failed");
		return;
	}

	wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
	wpabuf_put_u8(buf, WLAN_RRM_LINK_MEASUREMENT_REPORT);
	wpabuf_put_data(buf, &report, sizeof(report));
	wpa_hexdump_buf(MSG_DEBUG, "RRM: Link measurement report", buf);

	if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, src,
				wpa_s->own_addr, wpa_s->bssid,
				wpabuf_head(buf), wpabuf_len(buf), 0)) {
		wpa_printf(MSG_ERROR,
			   "RRM: Link measurement report failed. Send action failed");
	}
	wpabuf_free(buf);
}


int wpas_beacon_rep_scan_process(struct wpa_supplicant *wpa_s,
				 struct wpa_scan_results *scan_res,
				 struct scan_info *info)
{
	size_t i = 0;
	struct wpabuf *buf = NULL;

	if (!wpa_s->beacon_rep_data.token)
		return 0;

	if (!wpa_s->current_bss)
		goto out;

	/* If the measurement was aborted, don't report partial results */
	if (info->aborted)
		goto out;

	wpa_printf(MSG_DEBUG, "RRM: TSF BSSID: " MACSTR " current BSS: " MACSTR,
		   MAC2STR(info->scan_start_tsf_bssid),
		   MAC2STR(wpa_s->current_bss->bssid));
	if ((wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT) &&
	    os_memcmp(info->scan_start_tsf_bssid, wpa_s->current_bss->bssid,
		      ETH_ALEN) != 0) {
		wpa_printf(MSG_DEBUG,
			   "RRM: Ignore scan results due to mismatching TSF BSSID");
		goto out;
	}

	for (i = 0; i < scan_res->num; i++) {
		struct wpa_bss *bss =
			wpa_bss_get_bssid(wpa_s, scan_res->res[i]->bssid);

		if (!bss)
			continue;

		if ((wpa_s->drv_rrm_flags &
		     WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT) &&
		    os_memcmp(scan_res->res[i]->tsf_bssid,
			      wpa_s->current_bss->bssid, ETH_ALEN) != 0) {
			wpa_printf(MSG_DEBUG,
				   "RRM: Ignore scan result for " MACSTR
				   " due to mismatching TSF BSSID" MACSTR,
				   MAC2STR(scan_res->res[i]->bssid),
				   MAC2STR(scan_res->res[i]->tsf_bssid));
			continue;
		}

		/*
		 * Don't report results that were not received during the
		 * current measurement.
		 */
		if (!(wpa_s->drv_rrm_flags &
		      WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT)) {
			struct os_reltime update_time, diff;

			/* For now, allow 8 ms older results due to some
			 * unknown issue with cfg80211 BSS table updates during
			 * a scan with the current BSS.
			 * TODO: Fix this more properly to avoid having to have
			 * this type of hacks in place. */
			calculate_update_time(&scan_res->fetch_time,
					      scan_res->res[i]->age,
					      &update_time);
			os_reltime_sub(&wpa_s->beacon_rep_scan,
				       &update_time, &diff);
			if (os_reltime_before(&update_time,
					      &wpa_s->beacon_rep_scan) &&
			    (diff.sec || diff.usec >= 8000)) {
				wpa_printf(MSG_DEBUG,
					   "RRM: Ignore scan result for " MACSTR
					   " due to old update (age(ms) %u, calculated age %u.%06u seconds)",
					   MAC2STR(scan_res->res[i]->bssid),
					   scan_res->res[i]->age,
					   (unsigned int) diff.sec,
					   (unsigned int) diff.usec);
				continue;
			}
		} else if (info->scan_start_tsf >
			   scan_res->res[i]->parent_tsf) {
			continue;
		}

		if (wpas_add_beacon_rep(wpa_s, &buf, bss, info->scan_start_tsf,
					scan_res->res[i]->parent_tsf) < 0)
			break;
	}

	if (!buf && wpas_beacon_rep_no_results(wpa_s, &buf))
		goto out;

	wpa_hexdump_buf(MSG_DEBUG, "RRM: Radio Measurement report", buf);

	wpas_rrm_send_msr_report(wpa_s, buf);
	wpabuf_free(buf);

out:
	wpas_clear_beacon_rep_data(wpa_s);
	return 1;
}


void wpas_clear_beacon_rep_data(struct wpa_supplicant *wpa_s)
{
	struct beacon_rep_data *data = &wpa_s->beacon_rep_data;

	eloop_cancel_timeout(wpas_rrm_scan_timeout, wpa_s, NULL);
	bitfield_free(data->eids);
	os_free(data->scan_params.freqs);
	os_memset(data, 0, sizeof(*data));
}
