/* 
 * 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 = kmalloc(size, GFP_ATOMIC);
	memset(data, 0, size);
	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? */
}


/*****************************************************************************
 * 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 capability Info */
	(*pkt)->capability = (mac->ieee->iw_mode == IW_MODE_MASTER) || (mac->ieee->iw_mode == IW_MODE_INFRA) ?
		cpu_to_le16(WLAN_CAPABILITY_ESS) :
		cpu_to_le16(WLAN_CAPABILITY_IBSS);
	/* Need to add this
	(*pkt)->capability |= mac->ieee->short_slot ? 
			cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME) : 0;
	 */
	(*pkt)->capability |= mac->ieee->sec.level ? cpu_to_le16(WLAN_CAPABILITY_PRIVACY) : 0;
	/* 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 capability Info */
	(*pkt)->capability = mac->ieee->iw_mode == IW_MODE_MASTER ? 
				cpu_to_le16(WLAN_CAPABILITY_ESS) :
				cpu_to_le16(WLAN_CAPABILITY_IBSS);
	/*
	(*pkt)->capability |= mac->ieee->short_slot ? 
			cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME) : 0;
	 */
	(*pkt)->capability |= mac->ieee->sec.level ?
			cpu_to_le16(WLAN_CAPABILITY_PRIVACY) : 0;
		
	/* 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)
{
	u8 *data;
	/* Allocate Packet */
	(*pkt) = (struct ieee80211_auth *)ieee80211softmac_alloc_mgt(
		2 +		/* Auth Algorithm */
		2 +		/* Auth Transaction Seq */
		2 +		/* Status Code */
		 /* Challenge Text IE */
		mac->ieee->open_wep ? 0 : 
		1 + 1 + WLAN_AUTH_CHALLENGE_LEN
	);	
	if (unlikely((*pkt) == NULL))
		return 0;
	ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_AUTH, net->bssid, net->bssid);
		
	/* Algorithm */
	(*pkt)->algorithm = mac->ieee->open_wep ? 
		cpu_to_le16(WLAN_AUTH_OPEN) :
		cpu_to_le16(WLAN_AUTH_SHARED_KEY);
	/* Transaction */
	(*pkt)->transaction = cpu_to_le16(transaction);
	/* Status */
	(*pkt)->status = cpu_to_le16(status);
	
	data = (u8 *)(*pkt)->info_element;
	/* Challenge Text */
	if(!mac->ieee->open_wep){
		*data = MFIE_TYPE_CHALLENGE;
		data++;
		
		/* Copy the challenge in */
		// *data = challenge length
		// data += sizeof(u16);
		// memcpy(data, challenge, challenge length);
		// data += challenge length;
		
		/* Add the full size to the packet length */
	}

	/* 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;

	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));
		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, pkt_size);

	kfree(pkt);
	return 0;
}


/* Create an rts/cts frame */
static u32
ieee80211softmac_rts_cts(struct ieee80211_hdr_2addr **pkt,
	struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net, 
	u32 type)
{
	/* Allocate Packet */
	(*pkt) = kmalloc(IEEE80211_2ADDR_LEN, GFP_ATOMIC);	
	memset(*pkt, 0, IEEE80211_2ADDR_LEN);
	if((*pkt) == NULL)
		return 0;
	ieee80211softmac_hdr_2addr(mac, (*pkt), type, net->bssid);
	return IEEE80211_2ADDR_LEN;
}


/* Sends a control packet */
static int
ieee80211softmac_send_ctl_frame(struct ieee80211softmac_device *mac,
	struct ieee80211softmac_network *net, u32 type, u32 arg)
{
	void *pkt = NULL;
	u32 pkt_size = 0;
	
	switch(type) {
	case IEEE80211_STYPE_RTS:
	case IEEE80211_STYPE_CTS:
		pkt_size = ieee80211softmac_rts_cts((struct ieee80211_hdr_2addr **)(&pkt), mac, net, type);
		break;
	default:
		printkl(KERN_DEBUG PFX "Unsupported Control Frame type: %i\n", type);
		return -EINVAL;
	}

	if(pkt_size == 0)
		return -ENOMEM;
	
	/* Send the packet to the ieee80211 layer for tx */
	ieee80211_tx_frame(mac->ieee, (struct ieee80211_hdr *) pkt, pkt_size);

	kfree(pkt);
	return 0;
}
