/* -*-	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_bsfc_queue_h
#define ns_bsfc_queue_h

#include "connector.h"
#include "packet.h"
#include "ip.h"
#include <drop-tail.h>
#include "fc-queue.h"

#define MAX_NUM_UE_PER_CELL	100		// 100 for UMTS.

// structure for transmission control for each flow
struct user {
	nsaddr_t dest_;	// UE address
	double len_;	// support for bsfcHandler
	double bytes_per_tti_;	// bytes allowed to be transmitted in each tti_ for that UE
};

class BsFCQueue;

/*	Timer		*/

class BsFCTimer : public Handler {
public:
	BsFCTimer(BsFCQueue* 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:
	BsFCQueue *queue_;
	int	busy_;
	int	paused_;
	Event intr;
	double stime;	// start time
	double rtime;	// remaining time
  	static int verbose_;   // to include a verbose output ..
};

///////////////////////////////////////////////////////////////////////////////////////
/////////////////// class Base Station Flow Control Queue /////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////

class BsFCQueue : public DropTail {
  	friend class BsFCTimer;

public:
	BsFCQueue();
      int command(int argc, const char*const* argv);
	void recv(Packet* p, Handler*);

	int find(nsaddr_t dir);		// returns position in users_[] for a UE
	void reg(nsaddr_t dir, double l);	// register/de-register UE
	void bsfcHandler(Event *e);	// handler for BsFCTimer
	nsaddr_t ip_nodeb_;		// ip address of NodeB

	inline double tti() { return(tti_); }

protected:
	NsObject* callback_;	// for sending stored packets upwards in handover procedure

	double tti_;	// time for TTI
  	static int verbose_;   // to include a verbose output ..
	Event intr_;
  	Event intr; //

	user users_[MAX_NUM_UE];	// information about UEs
	BsFCTimer qTimer_;		// timer
};

#endif
