/*
 * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
 *
 * Marek Lindner, Simon Wunderlich
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA
 *
 */

#include "main.h"
#include "aggregation.h"
#include "send.h"
#include "routing.h"

/* calculate the size of the hna information for a given packet */
static int hna_len(struct batman_packet *batman_packet)
{
	return batman_packet->num_hna * ETH_ALEN;
}

/* return true if new_packet can be aggregated with forw_packet */
static bool can_aggregate_with(struct batman_packet *new_batman_packet,
			       int packet_len,
			       unsigned long send_time,
			       bool directlink,
			       struct batman_if *if_incoming,
			       struct forw_packet *forw_packet)
{
	struct batman_packet *batman_packet =
		(struct batman_packet *)forw_packet->packet_buff;
	int aggregated_bytes = forw_packet->packet_len + packet_len;

	/**
	 * we can aggregate the current packet to this aggregated packet
	 * if:
	 *
	 * - the send time is within our MAX_AGGREGATION_MS time
	 * - the resulting packet wont be bigger than
	 *   MAX_AGGREGATION_BYTES
	 */

	if (time_before(send_time, forw_packet->send_time) &&
	    (aggregated_bytes <= MAX_AGGREGATION_BYTES)) {

		/**
		 * check aggregation compatibility
		 * -> direct link packets are broadcasted on
		 *    their interface only
		 * -> aggregate packet if the current packet is
		 *    a "global" packet as well as the base
		 *    packet
		 */

		/* packets without direct link flag and high TTL
		 * are flooded through the net  */
		if ((!directlink) &&
		    (!(batman_packet->flags & DIRECTLINK)) &&
		    (batman_packet->ttl != 1) &&

		    /* own packets originating non-primary
		     * interfaces leave only that interface */
		    ((!forw_packet->own) ||
		     (forw_packet->if_incoming->if_num == 0)))
			return true;

		/* if the incoming packet is sent via this one
		 * interface only - we still can aggregate */
		if ((directlink) &&
		    (new_batman_packet->ttl == 1) &&
		    (forw_packet->if_incoming == if_incoming))
			return true;

	}

	return false;
}

/* create a new aggregated packet and add this packet to it */
static void new_aggregated_packet(unsigned char *packet_buff,
			   int packet_len,
			   unsigned long send_time,
			   bool direct_link,
			   struct batman_if *if_incoming,
			   int own_packet)
{
	struct forw_packet *forw_packet_aggr;
	unsigned long flags;

	forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
	if (!forw_packet_aggr)
		return;

	forw_packet_aggr->packet_buff = kmalloc(MAX_AGGREGATION_BYTES,
						GFP_ATOMIC);
	if (!forw_packet_aggr->packet_buff) {
		kfree(forw_packet_aggr);
		return;
	}

	INIT_HLIST_NODE(&forw_packet_aggr->list);

	forw_packet_aggr->packet_len = packet_len;
	memcpy(forw_packet_aggr->packet_buff,
	       packet_buff,
	       forw_packet_aggr->packet_len);

	forw_packet_aggr->skb = NULL;
	forw_packet_aggr->own = own_packet;
	forw_packet_aggr->if_incoming = if_incoming;
	forw_packet_aggr->num_packets = 0;
	forw_packet_aggr->direct_link_flags = 0;
	forw_packet_aggr->send_time = send_time;

	/* save packet direct link flag status */
	if (direct_link)
		forw_packet_aggr->direct_link_flags |= 1;

	/* add new packet to packet list */
	spin_lock_irqsave(&forw_bat_list_lock, flags);
	hlist_add_head(&forw_packet_aggr->list, &forw_bat_list);
	spin_unlock_irqrestore(&forw_bat_list_lock, flags);

	/* start timer for this packet */
	INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
			  send_outstanding_bat_packet);
	queue_delayed_work(bat_event_workqueue,
			   &forw_packet_aggr->delayed_work,
			   send_time - jiffies);
}

/* aggregate a new packet into the existing aggregation */
static void aggregate(struct forw_packet *forw_packet_aggr,
		      unsigned char *packet_buff,
		      int packet_len,
		      bool direct_link)
{
	memcpy((forw_packet_aggr->packet_buff + forw_packet_aggr->packet_len),
	       packet_buff, packet_len);
	forw_packet_aggr->packet_len += packet_len;
	forw_packet_aggr->num_packets++;

	/* save packet direct link flag status */
	if (direct_link)
		forw_packet_aggr->direct_link_flags |=
			(1 << forw_packet_aggr->num_packets);
}

void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len,
			    struct batman_if *if_incoming, char own_packet,
			    unsigned long send_time)
{
	/**
	 * _aggr -> pointer to the packet we want to aggregate with
	 * _pos -> pointer to the position in the queue
	 */
	struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL;
	struct hlist_node *tmp_node;
	struct batman_packet *batman_packet =
		(struct batman_packet *)packet_buff;
	bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0;
	unsigned long flags;

	/* find position for the packet in the forward queue */
	spin_lock_irqsave(&forw_bat_list_lock, flags);
	/* own packets are not to be aggregated */
	if ((atomic_read(&aggregation_enabled)) && (!own_packet)) {
		hlist_for_each_entry(forw_packet_pos, tmp_node, &forw_bat_list,
				     list) {
			if (can_aggregate_with(batman_packet,
					       packet_len,
					       send_time,
					       direct_link,
					       if_incoming,
					       forw_packet_pos)) {
				forw_packet_aggr = forw_packet_pos;
				break;
			}
		}
	}

	/* nothing to aggregate with - either aggregation disabled or no
	 * suitable aggregation packet found */
	if (forw_packet_aggr == NULL) {
		/* the following section can run without the lock */
		spin_unlock_irqrestore(&forw_bat_list_lock, flags);
		new_aggregated_packet(packet_buff, packet_len,
				      send_time, direct_link,
				      if_incoming, own_packet);
	} else {
		aggregate(forw_packet_aggr,
			  packet_buff, packet_len,
			  direct_link);
		spin_unlock_irqrestore(&forw_bat_list_lock, flags);
	}
}

/* unpack the aggregated packets and process them one by one */
void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
			     int packet_len, struct batman_if *if_incoming)
{
	struct batman_packet *batman_packet;
	int buff_pos = 0;
	unsigned char *hna_buff;

	batman_packet = (struct batman_packet *)packet_buff;

	while (aggregated_packet(buff_pos, packet_len,
				 batman_packet->num_hna)) {

		/* network to host order for our 16bit seqno, and the
		   orig_interval. */
		batman_packet->seqno = ntohs(batman_packet->seqno);

		hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
		receive_bat_packet(ethhdr, batman_packet,
				   hna_buff, hna_len(batman_packet),
				   if_incoming);

		buff_pos += BAT_PACKET_LEN + hna_len(batman_packet);
		batman_packet = (struct batman_packet *)
			(packet_buff + buff_pos);
	}
}
