/*
 * Some parts based on code from net80211
 * Copyright (c) 2001 Atsushi Onoe
 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "ieee80211softmac_priv.h"

/* Helper functions for inserting data into the frames */

/*
 * Adds an ESSID element to the frame
 *
 */
static u8 *
ieee80211softmac_add_essid(u8 *dst, struct ieee80211softmac_essid *essid)
{
	if (essid) {
		*dst++ = MFIE_TYPE_SSID;
		*dst++ = essid->len;
		memcpy(dst, essid->data, essid->len);
		return dst+essid->len;
	} else {
		*dst++ = MFIE_TYPE_SSID;
		*dst++ = 0;
		return dst;
	}
}

/* Adds Supported Rates and if required Extended Rates Information Element
 * to the frame, ASSUMES WE HAVE A SORTED LIST OF RATES */
static u8 *
ieee80211softmac_frame_add_rates(u8 *dst, const struct ieee80211softmac_ratesinfo *r)
{
	int cck_len, ofdm_len;
	*dst++ = MFIE_TYPE_RATES;

	for(cck_len=0; ieee80211_is_cck_rate(r->rates[cck_len]) && (cck_len < r->count);cck_len++);

	if(cck_len > IEEE80211SOFTMAC_MAX_RATES_LEN)
		cck_len = IEEE80211SOFTMAC_MAX_RATES_LEN;
	*dst++ = cck_len;
	memcpy(dst, r->rates, cck_len);
	dst += cck_len;

	if(cck_len < r->count){
		for (ofdm_len=0; ieee80211_is_ofdm_rate(r->rates[ofdm_len + cck_len]) && (ofdm_len + cck_len < r->count); ofdm_len++);
		if (ofdm_len > 0) {
			if (ofdm_len > IEEE80211SOFTMAC_MAX_EX_RATES_LEN)
				ofdm_len = IEEE80211SOFTMAC_MAX_EX_RATES_LEN;
			*dst++ = MFIE_TYPE_RATES_EX;
			*dst++ = ofdm_len;
			memcpy(dst, r->rates + cck_len, ofdm_len);
			dst += ofdm_len;
		}
	}
	return dst;
}

/* Allocate a management frame */
static u8 *
ieee80211softmac_alloc_mgt(u32 size)
{
	u8 * data;

	/* Add the header and FCS to the size */
	size = size + IEEE80211_3ADDR_LEN;
	if(size > IEEE80211_DATA_LEN)
		return NULL;
	/* Allocate the frame */
	data = kzalloc(size, GFP_ATOMIC);
	return data;
}

/*
 * Add a 2 Address Header
 */
static void
ieee80211softmac_hdr_2addr(struct ieee80211softmac_device *mac,
	struct ieee80211_hdr_2addr *header, u32 type, u8 *dest)
{
	/* Fill in the frame control flags */
	header->frame_ctl = cpu_to_le16(type);
	/* Control packets always have WEP turned off */
	if(type > IEEE80211_STYPE_CFENDACK && type < IEEE80211_STYPE_PSPOLL)
		header->frame_ctl |= mac->ieee->sec.level ? cpu_to_le16(IEEE80211_FCTL_PROTECTED) : 0;

	/* Fill in the duration */
	header->duration_id = 0;
	/* FIXME: How do I find this?
	 * calculate. But most drivers just fill in 0 (except if it's a station id of course) */

	/* Fill in the Destination Address */
	if(dest == NULL)
		memset(header->addr1, 0xFF, ETH_ALEN);
	else
		memcpy(header->addr1, dest, ETH_ALEN);
	/* Fill in the Source Address */
	memcpy(header->addr2, mac->ieee->dev->dev_addr, ETH_ALEN);

}


/* Add a 3 Address Header */
static void
ieee80211softmac_hdr_3addr(struct ieee80211softmac_device *mac,
	struct ieee80211_hdr_3addr *header, u32 type, u8 *dest, u8 *bssid)
{
	/* This is common with 2addr, so use that instead */
	ieee80211softmac_hdr_2addr(mac, (struct ieee80211_hdr_2addr *)header, type, dest);

	/* Fill in the BSS ID */
	if(bssid == NULL)
		memset(header->addr3, 0xFF, ETH_ALEN);
	else
		memcpy(header->addr3, bssid, ETH_ALEN);

	/* Fill in the sequence # */
	/* FIXME: I need to add this to the softmac struct
	 * shouldn't the sequence number be in ieee80211? */
}

static __le16
ieee80211softmac_capabilities(struct ieee80211softmac_device *mac,
	struct ieee80211softmac_network *net)
{
	__le16 capability = 0;

	/* ESS and IBSS bits are set according to the current mode */
	switch (mac->ieee->iw_mode) {
	case IW_MODE_INFRA:
		capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
		break;
	case IW_MODE_ADHOC:
		capability = cpu_to_le16(WLAN_CAPABILITY_IBSS);
		break;
	case IW_MODE_AUTO:
		capability = cpu_to_le16(net->capabilities &
			(WLAN_CAPABILITY_ESS|WLAN_CAPABILITY_IBSS));
		break;
	default:
		/* bleh. we don't ever go to these modes */
		printk(KERN_ERR PFX "invalid iw_mode!\n");
		break;
	}

	/* CF Pollable / CF Poll Request */
	/* Needs to be implemented, for now, the 0's == not supported */

	/* Privacy Bit */
	capability |= mac->ieee->sec.level ?
		cpu_to_le16(WLAN_CAPABILITY_PRIVACY) : 0;

	/* Short Preamble */
	/* Always supported: we probably won't ever be powering devices which
	 * dont support this... */
	capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);

	/* PBCC */
	/* Not widely used */

	/* Channel Agility */
	/* Not widely used */

	/* Short Slot */
	/* Will be implemented later */

	/* DSSS-OFDM */
	/* Not widely used */

	return capability;
}

/*****************************************************************************
 * Create Management packets
 *****************************************************************************/

/* Creates an association request packet */
static u32
ieee80211softmac_assoc_req(struct ieee80211_assoc_request **pkt,
	struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net)
{
	u8 *data;
	(*pkt) = (struct ieee80211_assoc_request *)ieee80211softmac_alloc_mgt(
		2 +		/* Capability Info */
		2 +	 	/* Listen Interval */
		/* SSID IE */
		1 + 1 + IW_ESSID_MAX_SIZE +
		/* Rates IE */
		1 + 1 + IEEE80211SOFTMAC_MAX_RATES_LEN +
		/* Extended Rates IE */
		1 + 1 + IEEE80211SOFTMAC_MAX_EX_RATES_LEN +
		/* WPA IE if present */
		mac->wpa.IElen
		/* Other IE's?  Optional?
		 * Yeah, probably need an extra IE parameter -- lots of vendors like to
		 * fill in their own IEs */
	);
	if (unlikely((*pkt) == NULL))
		return 0;
	ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_ASSOC_REQ, net->bssid, net->bssid);

	/* Fill in the capabilities */
	(*pkt)->capability = ieee80211softmac_capabilities(mac, net);

	/* Fill in Listen Interval (?) */
	(*pkt)->listen_interval = cpu_to_le16(10);

	data = (u8 *)(*pkt)->info_element;
	/* Add SSID */
	data = ieee80211softmac_add_essid(data, &net->essid);
	/* Add Rates */
	data = ieee80211softmac_frame_add_rates(data, &mac->ratesinfo);
	/* Add WPA IE */
	if (mac->wpa.IElen && mac->wpa.IE) {
		memcpy(data, mac->wpa.IE, mac->wpa.IElen);
		data += mac->wpa.IElen;
	}
	/* Return the number of used bytes */
	return (data - (u8*)(*pkt));
}

/* Create a reassociation request packet */
static u32
ieee80211softmac_reassoc_req(struct ieee80211_reassoc_request **pkt,
	struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net)
{
	u8 *data;
	(*pkt) = (struct ieee80211_reassoc_request *)ieee80211softmac_alloc_mgt(
		2 +		/* Capability Info */
		2 +	 	/* Listen Interval */
		ETH_ALEN +	/* AP MAC */
		/* SSID IE */
		1 + 1 + IW_ESSID_MAX_SIZE +
		/* Rates IE */
		1 + 1 + IEEE80211SOFTMAC_MAX_RATES_LEN +
		/* Extended Rates IE */
		1 + 1 + IEEE80211SOFTMAC_MAX_EX_RATES_LEN
		/* Other IE's? */
	);
	if (unlikely((*pkt) == NULL))
		return 0;
	ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_REASSOC_REQ, net->bssid, net->bssid);

	/* Fill in the capabilities */
	(*pkt)->capability = ieee80211softmac_capabilities(mac, net);

	/* Fill in Listen Interval (?) */
	(*pkt)->listen_interval = cpu_to_le16(10);
	/* Fill in the current AP MAC */
	memcpy((*pkt)->current_ap, mac->ieee->bssid, ETH_ALEN);

	data = (u8 *)(*pkt)->info_element;
	/* Add SSID */
	data = ieee80211softmac_add_essid(data, &net->essid);
	/* Add Rates */
	data = ieee80211softmac_frame_add_rates(data, &mac->ratesinfo);
	/* Return packet size */
	return (data - (u8 *)(*pkt));
}

/* Create an authentication packet */
static u32
ieee80211softmac_auth(struct ieee80211_auth **pkt,
	struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net,
	u16 transaction, u16 status, int *encrypt_mpdu)
{
	u8 *data;
	int auth_mode = mac->ieee->sec.auth_mode;
	int is_shared_response = (auth_mode == WLAN_AUTH_SHARED_KEY
		&& transaction == IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE);

	/* Allocate Packet */
	(*pkt) = (struct ieee80211_auth *)ieee80211softmac_alloc_mgt(
		2 +		/* Auth Algorithm */
		2 +		/* Auth Transaction Seq */
		2 +		/* Status Code */
		 /* Challenge Text IE */
		(is_shared_response ? 1 + 1 + net->challenge_len : 0)
	);
	if (unlikely((*pkt) == NULL))
		return 0;
	ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_AUTH, net->bssid, net->bssid);

	/* Algorithm */
	(*pkt)->algorithm = cpu_to_le16(auth_mode);
	/* Transaction */
	(*pkt)->transaction = cpu_to_le16(transaction);
	/* Status */
	(*pkt)->status = cpu_to_le16(status);

	data = (u8 *)(*pkt)->info_element;
	/* Challenge Text */
	if (is_shared_response) {
		*data = MFIE_TYPE_CHALLENGE;
		data++;

		/* Copy the challenge in */
		*data = net->challenge_len;
		data++;
		memcpy(data, net->challenge, net->challenge_len);
		data += net->challenge_len;

		/* Make sure this frame gets encrypted with the shared key */
		*encrypt_mpdu = 1;
	} else
		*encrypt_mpdu = 0;

	/* Return the packet size */
	return (data - (u8 *)(*pkt));
}

/* Create a disassocation or deauthentication packet */
static u32
ieee80211softmac_disassoc_deauth(struct ieee80211_disassoc **pkt,
	struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net,
	u16 type, u16 reason)
{
	/* Allocate Packet */
	(*pkt) = (struct ieee80211_disassoc *)ieee80211softmac_alloc_mgt(2);
	if (unlikely((*pkt) == NULL))
		return 0;
	ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), type, net->bssid, net->bssid);
	/* Reason */
	(*pkt)->reason = cpu_to_le16(reason);
	/* Return the packet size */
	return (2 + IEEE80211_3ADDR_LEN);
}

/* Create a probe request packet */
static u32
ieee80211softmac_probe_req(struct ieee80211_probe_request **pkt,
	struct ieee80211softmac_device *mac, struct ieee80211softmac_essid *essid)
{
	u8 *data;
	/* Allocate Packet */
	(*pkt) = (struct ieee80211_probe_request *)ieee80211softmac_alloc_mgt(
		/* SSID of requested network */
		1 + 1 + IW_ESSID_MAX_SIZE +
		/* Rates IE */
		1 + 1 + IEEE80211SOFTMAC_MAX_RATES_LEN +
		/* Extended Rates IE */
		1 + 1 + IEEE80211SOFTMAC_MAX_EX_RATES_LEN
	);
	if (unlikely((*pkt) == NULL))
		return 0;
	ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_PROBE_REQ, NULL, NULL);

	data = (u8 *)(*pkt)->info_element;
	/* Add ESSID (can be NULL) */
	data = ieee80211softmac_add_essid(data, essid);
	/* Add Rates */
	data = ieee80211softmac_frame_add_rates(data, &mac->ratesinfo);
	/* Return packet size */
	return (data - (u8 *)(*pkt));
}

/* Create a probe response packet */
/* FIXME: Not complete */
static u32
ieee80211softmac_probe_resp(struct ieee80211_probe_response **pkt,
	struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net)
{
	u8 *data;
	/* Allocate Packet */
	(*pkt) = (struct ieee80211_probe_response *)ieee80211softmac_alloc_mgt(
		8 +		/* Timestamp */
		2 +		/* Beacon Interval */
		2 +		/* Capability Info */
				/* SSID IE */
		1 + 1 + IW_ESSID_MAX_SIZE +
		7 + 		/* FH Parameter Set */
		2 +		/* DS Parameter Set */
		8 +		/* CF Parameter Set */
		4 		/* IBSS Parameter Set */
	);
	if (unlikely((*pkt) == NULL))
		return 0;
	ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_PROBE_RESP, net->bssid, net->bssid);
	data = (u8 *)(*pkt)->info_element;

	/* Return the packet size */
	return (data - (u8 *)(*pkt));
}


/* Sends a manangement packet
 * FIXME: document the use of the arg parameter
 * for _AUTH: (transaction #) | (status << 16)
 */
int
ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
	void *ptrarg, u32 type, u32 arg)
{
	void *pkt = NULL;
	u32 pkt_size = 0;
	int encrypt_mpdu = 0;

	switch(type) {
	case IEEE80211_STYPE_ASSOC_REQ:
		pkt_size = ieee80211softmac_assoc_req((struct ieee80211_assoc_request **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg);
		break;
	case IEEE80211_STYPE_REASSOC_REQ:
		pkt_size = ieee80211softmac_reassoc_req((struct ieee80211_reassoc_request **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg);
		break;
	case IEEE80211_STYPE_AUTH:
		pkt_size = ieee80211softmac_auth((struct ieee80211_auth **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg, (u16)(arg & 0xFFFF), (u16) (arg >> 16), &encrypt_mpdu);
		break;
	case IEEE80211_STYPE_DISASSOC:
	case IEEE80211_STYPE_DEAUTH:
		pkt_size = ieee80211softmac_disassoc_deauth((struct ieee80211_disassoc **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg, type, (u16)(arg & 0xFFFF));
		break;
	case IEEE80211_STYPE_PROBE_REQ:
		pkt_size = ieee80211softmac_probe_req((struct ieee80211_probe_request **)(&pkt), mac, (struct ieee80211softmac_essid *)ptrarg);
		break;
	case IEEE80211_STYPE_PROBE_RESP:
		pkt_size = ieee80211softmac_probe_resp((struct ieee80211_probe_response **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg);
		break;
	default:
		printkl(KERN_DEBUG PFX "Unsupported Management Frame type: %i\n", type);
		return -EINVAL;
	};

	if(pkt_size == 0 || pkt == NULL) {
		printkl(KERN_DEBUG PFX "Error, packet is nonexistant or 0 length\n");
		return -ENOMEM;
	}

	/* Send the packet to the ieee80211 layer for tx */
	/* we defined softmac->mgmt_xmit for this. Should we keep it
	 * as it is (that means we'd need to wrap this into a txb),
	 * modify the prototype (so it matches this function),
	 * or get rid of it alltogether?
	 * Does this work for you now?
	 */
	ieee80211_tx_frame(mac->ieee, (struct ieee80211_hdr *)pkt,
		IEEE80211_3ADDR_LEN, pkt_size, encrypt_mpdu);

	kfree(pkt);
	return 0;
}

/* Beacon handling */
int ieee80211softmac_handle_beacon(struct net_device *dev,
	struct ieee80211_beacon *beacon,
	struct ieee80211_network *network)
{
	struct ieee80211softmac_device *mac = ieee80211_priv(dev);

	/* This might race, but we don't really care and it's not worth
	 * adding heavyweight locking in this fastpath.
	 */
	if (mac->associnfo.associated) {
		if (memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0)
			ieee80211softmac_process_erp(mac, network->erp_value);
	}

	return 0;
}

