/*
 * Received frame processing
 * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
 *
 * 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/radiotap.h"
#include "utils/radiotap_iter.h"
#include "common/ieee802_11_defs.h"
#include "common/qca-vendor.h"
#include "wlantest.h"


static struct wlantest_sta * rx_get_sta(struct wlantest *wt,
					const struct ieee80211_hdr *hdr,
					size_t len, int *to_ap)
{
	u16 fc;
	const u8 *sta_addr, *bssid;
	struct wlantest_bss *bss;

	*to_ap = 0;
	if (hdr->addr1[0] & 0x01)
		return NULL; /* Ignore group addressed frames */

	fc = le_to_host16(hdr->frame_control);
	switch (WLAN_FC_GET_TYPE(fc)) {
	case WLAN_FC_TYPE_MGMT:
		if (len < 24)
			return NULL;
		bssid = hdr->addr3;
		if (os_memcmp(bssid, hdr->addr2, ETH_ALEN) == 0) {
			sta_addr = hdr->addr1;
			*to_ap = 0;
		} else {
			if (os_memcmp(bssid, hdr->addr1, ETH_ALEN) != 0)
				return NULL; /* Unsupported STA-to-STA frame */
			sta_addr = hdr->addr2;
			*to_ap = 1;
		}
		break;
	case WLAN_FC_TYPE_DATA:
		if (len < 24)
			return NULL;
		switch (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
		case 0:
			return NULL; /* IBSS not supported */
		case WLAN_FC_FROMDS:
			sta_addr = hdr->addr1;
			bssid = hdr->addr2;
			*to_ap = 0;
			break;
		case WLAN_FC_TODS:
			sta_addr = hdr->addr2;
			bssid = hdr->addr1;
			*to_ap = 1;
			break;
		case WLAN_FC_TODS | WLAN_FC_FROMDS:
			return NULL; /* WDS not supported */
		default:
			return NULL;
		}
		break;
	case WLAN_FC_TYPE_CTRL:
		if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PSPOLL &&
		    len >= 16) {
			sta_addr = hdr->addr2;
			bssid = hdr->addr1;
			*to_ap = 1;
		} else
			return NULL;
		break;
	default:
		return NULL;
	}

	bss = bss_find(wt, bssid);
	if (bss == NULL)
		return NULL;
	return sta_find(bss, sta_addr);
}


static void rx_update_ps(struct wlantest *wt, const struct ieee80211_hdr *hdr,
			 size_t len, struct wlantest_sta *sta, int to_ap)
{
	u16 fc, type, stype;

	if (sta == NULL)
		return;

	fc = le_to_host16(hdr->frame_control);
	type = WLAN_FC_GET_TYPE(fc);
	stype = WLAN_FC_GET_STYPE(fc);

	if (!to_ap) {
		if (sta->pwrmgt && !sta->pspoll) {
			u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
			add_note(wt, MSG_DEBUG, "AP " MACSTR " sent a frame "
				 "(%u:%u) to a sleeping STA " MACSTR
				 " (seq=%u)",
				 MAC2STR(sta->bss->bssid),
				 type, stype, MAC2STR(sta->addr),
				 WLAN_GET_SEQ_SEQ(seq_ctrl));
		} else
			sta->pspoll = 0;
		return;
	}

	sta->pspoll = 0;

	if (type == WLAN_FC_TYPE_DATA || type == WLAN_FC_TYPE_MGMT ||
	    (type == WLAN_FC_TYPE_CTRL && stype == WLAN_FC_STYPE_PSPOLL)) {
		/*
		 * In theory, the PS state changes only at the end of the frame
		 * exchange that is ACKed by the AP. However, most cases are
		 * handled with this simpler implementation that does not
		 * maintain state through the frame exchange.
		 */
		if (sta->pwrmgt && !(fc & WLAN_FC_PWRMGT)) {
			add_note(wt, MSG_DEBUG, "STA " MACSTR " woke up from "
				 "sleep", MAC2STR(sta->addr));
			sta->pwrmgt = 0;
		} else if (!sta->pwrmgt && (fc & WLAN_FC_PWRMGT)) {
			add_note(wt, MSG_DEBUG, "STA " MACSTR " went to sleep",
				 MAC2STR(sta->addr));
			sta->pwrmgt = 1;
		}
	}

	if (type == WLAN_FC_TYPE_CTRL && stype == WLAN_FC_STYPE_PSPOLL)
		sta->pspoll = 1;
}


static int rx_duplicate(struct wlantest *wt, const struct ieee80211_hdr *hdr,
			size_t len, struct wlantest_sta *sta, int to_ap)
{
	u16 fc;
	int tid = 16;
	le16 *seq_ctrl;

	if (sta == NULL)
		return 0;

	fc = le_to_host16(hdr->frame_control);
	if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
	    (WLAN_FC_GET_STYPE(fc) & 0x08) && len >= 26) {
		const u8 *qos = ((const u8 *) hdr) + 24;
		tid = qos[0] & 0x0f;
	}

	if (to_ap)
		seq_ctrl = &sta->seq_ctrl_to_ap[tid];
	else
		seq_ctrl = &sta->seq_ctrl_to_sta[tid];

	if ((fc & WLAN_FC_RETRY) && hdr->seq_ctrl == *seq_ctrl) {
		u16 s = le_to_host16(hdr->seq_ctrl);
		add_note(wt, MSG_MSGDUMP, "Ignore duplicated frame (seq=%u "
			 "frag=%u A1=" MACSTR " A2=" MACSTR ")",
			 WLAN_GET_SEQ_SEQ(s), WLAN_GET_SEQ_FRAG(s),
			 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2));
		return 1;
	}

	*seq_ctrl = hdr->seq_ctrl;

	return 0;
}


static void rx_ack(struct wlantest *wt, const struct ieee80211_hdr *hdr)
{
	struct ieee80211_hdr *last = (struct ieee80211_hdr *) wt->last_hdr;
	u16 fc;

	if (wt->last_len < 24 || (last->addr1[0] & 0x01) ||
	    os_memcmp(hdr->addr1, last->addr2, ETH_ALEN) != 0) {
		add_note(wt, MSG_MSGDUMP, "Unknown Ack frame (previous frame "
			 "not seen)");
		return;
	}

	/* Ack to the previous frame */
	fc = le_to_host16(last->frame_control);
	if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT)
		rx_mgmt_ack(wt, last);
}


static void rx_frame(struct wlantest *wt, const u8 *data, size_t len)
{
	const struct ieee80211_hdr *hdr;
	u16 fc;
	struct wlantest_sta *sta;
	int to_ap;

	wpa_hexdump(MSG_EXCESSIVE, "RX frame", data, len);
	if (len < 2)
		return;

	hdr = (const struct ieee80211_hdr *) data;
	fc = le_to_host16(hdr->frame_control);
	if (fc & WLAN_FC_PVER) {
		wpa_printf(MSG_DEBUG, "Drop RX frame with unexpected pver=%d",
			   fc & WLAN_FC_PVER);
		return;
	}

	sta = rx_get_sta(wt, hdr, len, &to_ap);

	switch (WLAN_FC_GET_TYPE(fc)) {
	case WLAN_FC_TYPE_MGMT:
		if (len < 24)
			break;
		if (rx_duplicate(wt, hdr, len, sta, to_ap))
			break;
		rx_update_ps(wt, hdr, len, sta, to_ap);
		rx_mgmt(wt, data, len);
		break;
	case WLAN_FC_TYPE_CTRL:
		if (len < 10)
			break;
		wt->rx_ctrl++;
		rx_update_ps(wt, hdr, len, sta, to_ap);
		if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACK)
			rx_ack(wt, hdr);
		break;
	case WLAN_FC_TYPE_DATA:
		if (len < 24)
			break;
		if (rx_duplicate(wt, hdr, len, sta, to_ap))
			break;
		rx_update_ps(wt, hdr, len, sta, to_ap);
		rx_data(wt, data, len);
		break;
	default:
		wpa_printf(MSG_DEBUG, "Drop RX frame with unexpected type %d",
			   WLAN_FC_GET_TYPE(fc));
		break;
	}

	os_memcpy(wt->last_hdr, data, len > sizeof(wt->last_hdr) ?
		  sizeof(wt->last_hdr) : len);
	wt->last_len = len;
}


static void tx_status(struct wlantest *wt, const u8 *data, size_t len, int ack)
{
	wpa_printf(MSG_DEBUG, "TX status: ack=%d", ack);
	wpa_hexdump(MSG_EXCESSIVE, "TX status frame", data, len);
}


static int check_fcs(const u8 *frame, size_t frame_len, const u8 *fcs)
{
	if (WPA_GET_LE32(fcs) != crc32(frame, frame_len))
		return -1;
	return 0;
}


void wlantest_process(struct wlantest *wt, const u8 *data, size_t len)
{
	struct ieee80211_radiotap_iterator iter;
	int ret;
	int rxflags = 0, txflags = 0, failed = 0, fcs = 0;
	const u8 *frame, *fcspos;
	size_t frame_len;

	wpa_hexdump(MSG_EXCESSIVE, "Process data", data, len);

	if (ieee80211_radiotap_iterator_init(&iter, (void *) data, len, NULL)) {
		add_note(wt, MSG_INFO, "Invalid radiotap frame");
		return;
	}

	for (;;) {
		ret = ieee80211_radiotap_iterator_next(&iter);
		wpa_printf(MSG_EXCESSIVE, "radiotap iter: %d "
			   "this_arg_index=%d", ret, iter.this_arg_index);
		if (ret == -ENOENT)
			break;
		if (ret) {
			add_note(wt, MSG_INFO, "Invalid radiotap header: %d",
				 ret);
			return;
		}
		switch (iter.this_arg_index) {
		case IEEE80211_RADIOTAP_FLAGS:
			if (*iter.this_arg & IEEE80211_RADIOTAP_F_FCS)
				fcs = 1;
			break;
		case IEEE80211_RADIOTAP_RX_FLAGS:
			rxflags = 1;
			break;
		case IEEE80211_RADIOTAP_TX_FLAGS:
			txflags = 1;
			failed = le_to_host16((*(u16 *) iter.this_arg)) &
				IEEE80211_RADIOTAP_F_TX_FAIL;
			break;
		case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
			if (WPA_GET_BE24(iter.this_arg) == OUI_QCA &&
			    iter.this_arg[3] == QCA_RADIOTAP_VID_WLANTEST) {
				add_note(wt, MSG_DEBUG,
					 "Skip frame inserted by wlantest");
				return;
			}
		}
	}

	frame = data + iter._max_length;
	frame_len = len - iter._max_length;

	if (fcs && frame_len >= 4) {
		frame_len -= 4;
		fcspos = frame + frame_len;
		if (check_fcs(frame, frame_len, fcspos) < 0) {
			add_note(wt, MSG_EXCESSIVE, "Drop RX frame with "
				 "invalid FCS");
			wt->fcs_error++;
			return;
		}
	}

	if (rxflags && txflags)
		return;
	if (!txflags)
		rx_frame(wt, frame, frame_len);
	else {
		add_note(wt, MSG_EXCESSIVE, "TX status - process as RX of "
			 "local frame");
		tx_status(wt, frame, frame_len, !failed);
		/* Process as RX frame to support local monitor interface */
		rx_frame(wt, frame, frame_len);
	}
}


void wlantest_process_prism(struct wlantest *wt, const u8 *data, size_t len)
{
	int fcs = 0;
	const u8 *frame, *fcspos;
	size_t frame_len;
	u32 hdrlen;

	wpa_hexdump(MSG_EXCESSIVE, "Process data", data, len);

	if (len < 8)
		return;
	hdrlen = WPA_GET_LE32(data + 4);

	if (len < hdrlen) {
		wpa_printf(MSG_INFO, "Too short frame to include prism "
			   "header");
		return;
	}

	frame = data + hdrlen;
	frame_len = len - hdrlen;
	fcs = 1;

	if (fcs && frame_len >= 4) {
		frame_len -= 4;
		fcspos = frame + frame_len;
		if (check_fcs(frame, frame_len, fcspos) < 0) {
			add_note(wt, MSG_EXCESSIVE, "Drop RX frame with "
				 "invalid FCS");
			wt->fcs_error++;
			return;
		}
	}

	rx_frame(wt, frame, frame_len);
}


void wlantest_process_80211(struct wlantest *wt, const u8 *data, size_t len)
{
	wpa_hexdump(MSG_EXCESSIVE, "Process data", data, len);

	if (wt->assume_fcs && len >= 4) {
		const u8 *fcspos;

		len -= 4;
		fcspos = data + len;
		if (check_fcs(data, len, fcspos) < 0) {
			add_note(wt, MSG_EXCESSIVE, "Drop RX frame with "
				 "invalid FCS");
			wt->fcs_error++;
			return;
		}
	}

	rx_frame(wt, data, len);
}
