/* -*-	Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */

/* By Pablo Martin and Paula Ballester,
 * Strathclyde University, Glasgow.
 * June, 2003.
*/

/* Copyright (c) 2003 Strathclyde University of Glasgow, Scotland.
 * 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 and binary code must contain
 * the above copyright notice, this list of conditions and the following
 * disclaimer.
 *
 * 2. All advertising materials mentioning features or use of this software
 * must display the following acknowledgement:
 * This product includes software developed at Strathclyde University of
 * Glasgow, Scotland.
 *
 * 3. The name of the University may not be used to endorse or promote
 * products derived from this software without specific prior written
 * permission.
 * STRATHCLYDE UNIVERSITY OF GLASGOW, MAKES NO REPRESENTATIONS
 * CONCERNING EITHER THE MERCHANTABILITY OF THIS SOFTWARE OR THE
 * SUITABILITY OF THIS SOFTWARE FOR ANY PARTICULAR PURPOSE.  The software
 * is provided "as is" without express or implied warranty of any kind.
*/

#ifndef ns_fc_queue_h
#define ns_fc_queue_h

#include "connector.h"
#include "packet.h"
#include "ip.h"
#include <drop-tail.h>
#include "phy-umts.h"

#define TTI			0.01	// 10 miliseconds for UMTS.

class FCQueue;

/*	Timer		*/

class FCTimer : public Handler {
public:
	FCTimer(FCQueue* m, double s = 0) : queue_(m) {
		busy_ = paused_ = 0; stime = rtime = 0.0;
	}

	void handle(Event *e);
	void start(Packet *p, double time);
	void stop(Packet *p);
	virtual void pause(void) { assert(0); }
	virtual void resume(void) { assert(0); }
	inline int busy(void) { return busy_; }
	inline int paused(void) { return paused_; }

protected:
	FCQueue *queue_;
	int	busy_;
	int	paused_;
	Event intr;
	double stime;	// start time
	double rtime;	// remaining time
  	static int verbose_;   // to include a verbose output ..
};

// structure for transmission control for each flow
struct ifq_control {
	int flowid_;	// flow id
	double bytes_per_tti_;	// bytes allowed to be transmitted in each tti_
	double len;			// support for fcHandler
};

///////////////////////////////////////////////////////////////////////////////////////
///////////////////////// class Flow Control Queue ////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////

class FCQueue : public DropTail {
  	friend class FCTimer;

public:
	FCQueue();
      int command(int argc, const char*const* argv);

	void recv(Packet* p, Handler*);
	void reg(int flow, double l);	// register and de-register for a flow
	int get_pos(int flow);		// return position in ifqc[] for flow
	void fcHandler(Event *e);	// handler of FCTimer
	
	nsaddr_t ip_ue_;
	inline double tti() { return(tti_); }

protected:
	double tti_;	// time corresponding to a TTI

	static int verbose_;   // to include a verbose output ..
	Event intr_;
  	Event intr;

private:
	ifq_control ifqc[MAX_NUM_FLOWS];	// information about flows

	FCTimer qTimer_;	// timer
};

#endif
