/*											/*
 * Copyright (c) 2000 Nortel Networks							 * Copyright (c) 2000 Nortel Networks
 * All rights reserved.									 * All rights reserved.
 * 											 * 
 * Redistribution and use in source and binary forms, with or without			 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions			 * modification, are permitted provided that the following conditions
 * are met:										 * are met:
 * 1. Redistributions of source code must retain the above copyright			 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.			 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright			 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the		 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.		 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software		 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:					 *    must display the following acknowledgement:
 *      This product includes software developed by Nortel Networks.			 *      This product includes software developed by Nortel Networks.
 * 4. The name of the Nortel Networks may not be used					 * 4. The name of the Nortel Networks may not be used
 *    to endorse or promote products derived from this software without			 *    to endorse or promote products derived from this software without
 *    specific prior written permission.						 *    specific prior written permission.
 * 											 * 
 * THIS SOFTWARE IS PROVIDED BY NORTEL AND CONTRIBUTORS ``AS IS'' AND			 * THIS SOFTWARE IS PROVIDED BY NORTEL AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE		 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE		 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL NORTEL OR CONTRIBUTORS BE LIABLE			 * ARE DISCLAIMED.  IN NO EVENT SHALL NORTEL OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL		 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS		 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)		 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT		 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY		 * 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		 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.										 * SUCH DAMAGE.
 *											 *
 * Developed by: Farhan Shallwani, Jeremy Ethridge					 * Developed by: Farhan Shallwani, Jeremy Ethridge
 *               Peter Pieda, and Mandeep Baines					 *               Peter Pieda, and Mandeep Baines
 * Maintainer: Peter Pieda <ppieda@nortelnetworks.com>					 * Maintainer: Peter Pieda <ppieda@nortelnetworks.com>
 */											 */

/*											/*
 * dsred.h										 * dsred.h
 *											 *
 * The Positions of dsREDQueue, edgeQueue, and coreQueue in the Object Hierarchy.	 * The Positions of dsREDQueue, edgeQueue, and coreQueue in the Object Hierarchy.
 *											 *
 * This class, i.e. "dsREDQueue", is positioned in the class hierarchy as follows:	 * This class, i.e. "dsREDQueue", is positioned in the class hierarchy as follows:
 *											 *
 *             Queue									 *             Queue
 *               |									 *               |
 *           dsREDQueue									 *           dsREDQueue
 *											 *
 *											 *
 *   This class stands for "Differentiated Services RED Queue".  Since the		 *   This class stands for "Differentiated Services RED Queue".  Since the
 * original RED does not support multiple parameters, and other functionality		 * original RED does not support multiple parameters, and other functionality
 * needed by a RED gateway in a Diffserv architecture, this class was created to	 * needed by a RED gateway in a Diffserv architecture, this class was created to
 * support the desired functionality.  This class is then inherited by two more		 * support the desired functionality.  This class is then inherited by two more
 * classes, moulding the old hierarchy as follows:					 * classes, moulding the old hierarchy as follows:
 *											 *
 *											 *
 *             Queue									 *             Queue
 *               |									 *               |
 *           dsREDQueue									 *           dsREDQueue
 *           |        |									 *           |        |
 *     edgeQueue    coreQueue								 *     edgeQueue    coreQueue
 *											 *
 *											 *
 * These child classes correspond to the "edge" and "core" routers in a Diffserv	 * These child classes correspond to the "edge" and "core" routers in a Diffserv
 * architecture.									 * architecture.
 *											 *
 */											 */


#ifndef dsred_h										#ifndef dsred_h
#define dsred_h										#define dsred_h

#include "red.h"	// need RED class specs (edp definition, for example)		#include "red.h"	// need RED class specs (edp definition, for example)
#include "queue.h"	// need Queue class specs					#include "queue.h"	// need Queue class specs
#include "dsredq.h"									#include "dsredq.h"


/* The dsRED class supports the creation of up to MAX_QUEUES physical queues at		/* The dsRED class supports the creation of up to MAX_QUEUES physical queues at
each network device, with up to MAX_PREC virtual queues in each queue. */ 		each network device, with up to MAX_PREC virtual queues in each queue. */ 
#define MAX_QUEUES 8// maximum number of physical RED queues				#define MAX_QUEUES 8// maximum number of physical RED queues
#define MAX_PREC 3	// maximum number of virtual RED queues in one physical queue	#define MAX_PREC 3	// maximum number of virtual RED queues in one physical queue
#define MAX_CP 40	// maximum number of code points in a simulation		#define MAX_CP 40	// maximum number of code points in a simulation
#define MEAN_PKT_SIZE 1000 	// default mean packet size, in bytes, needed for RED	#define MEAN_PKT_SIZE 1000 	// default mean packet size, in bytes, needed for RED
#define MAX_FLOWS 2500								      <

enum schedModeType {schedModeRR, schedModeWRR, schedModeWIRR, schedModePRI};		enum schedModeType {schedModeRR, schedModeWRR, schedModeWIRR, schedModePRI};

#define PKT_MARKED 3									#define PKT_MARKED 3
#define PKT_EDROPPED 2									#define PKT_EDROPPED 2
#define PKT_ENQUEUED 1									#define PKT_ENQUEUED 1
#define PKT_DROPPED 0									#define PKT_DROPPED 0


/*------------------------------------------------------------------------------	/*------------------------------------------------------------------------------
struct phbParam										struct phbParam
    This struct is used to maintain entries for the PHB parameter table, used 		    This struct is used to maintain entries for the PHB parameter table, used 
to map a code point to a physical queue-virtual queue pair.				to map a code point to a physical queue-virtual queue pair.
------------------------------------------------------------------------------*/	------------------------------------------------------------------------------*/
struct phbParam {									struct phbParam {
   int codePt_;										   int codePt_;
   int queue_;	// physical queue							   int queue_;	// physical queue
   int prec_;	// virtual queue (drop precedence)					   int prec_;	// virtual queue (drop precedence)
};											};

struct statType {									struct statType {
	long drops;       // per queue stats							long drops;       // per queue stats
	long edrops;										long edrops;
	long pkts;										long pkts;
	long valid_CP[MAX_CP];  // per CP stats							long valid_CP[MAX_CP];  // per CP stats
	long drops_CP[MAX_CP];									long drops_CP[MAX_CP];
	long edrops_CP[MAX_CP];									long edrops_CP[MAX_CP];
	long pkts_CP[MAX_CP];									long pkts_CP[MAX_CP];
};											};


struct detailedStatType {							      <
   long p_arr;     // packets arrived						      <
   long p_enq;     // packets enqueued						      <
   long p_deq;     // packets dequeued						      <
   long p_mark;    // packets marked						      <
   long p_drop;    // packets dropped						      <
   long p_edrop;   // packets early dropped					      <
   										      <
   long b_arr;     // bytes arrived						      <
   long b_enq;     // bytes enqueued						      <
   long b_deq;     // bytes dequeued						      <
   long b_mark;    // bytes marked						      <
   long b_drop;    // bytes dropped						      <
   long b_edrop;   // bytes early dropped					      <
   										      <
   float qdelay;								      <
   										      <
   double last_reset;								      <
};										      <
										      <
enum statQueryType {								      <
   DROPS,									      <
   EDROPS,									      <
   PKTS,									      <
   MARKS,									      <
   LAST_RESET,									      <
   LAST_PKT,									      <
   STAT_QUERY_SIZE								      <
};										      <
										      <
										      <
										      <
/*-----------------------------------------------------------------------------		/*-----------------------------------------------------------------------------
class dsREDQueue 									class dsREDQueue 
    This class specifies the characteristics for a Diffserv RED router.			    This class specifies the characteristics for a Diffserv RED router.
-----------------------------------------------------------------------------*/		-----------------------------------------------------------------------------*/
class dsREDQueue : public Queue {							class dsREDQueue : public Queue {
 public:										 public:	
  dsREDQueue();										  dsREDQueue();
  int command(int argc, const char*const* argv);	// interface to ns scripts	  int command(int argc, const char*const* argv);	// interface to ns scripts
  void clearDelayHistogram();							      |	  
  void printDelayHistogram();							      <
  float getDelay(int q, int prec);						      <
										      <
 protected:										 protected:
  Tcl_Channel channel_;								      <
  redQueue redq_[MAX_QUEUES];	// the physical queues at the router			  redQueue redq_[MAX_QUEUES];	// the physical queues at the router
  NsObject* de_drop_;		// drop_early target					  NsObject* de_drop_;		// drop_early target
  statType stats;               // used for statistics gatherings		      |	  statType stats; // used for statistics gatherings
  										      <
  /* used for statistics gatherings						      <
     this ptr is NULLed in the constructor and memory is allocated once		      <
     a channel is attached. If no channel is allocated, than statistics are not	      <
     collected									      <
   */										      <
  detailedStatType *ds;         						      <
  										      <
  int qToDq;			// current queue to be dequeued in a round robin mann	  int qToDq;			// current queue to be dequeued in a round robin mann
  int numQueues_;		// the number of physical queues at the router		  int numQueues_;		// the number of physical queues at the router
  int numPrec;		        // the number of virtual queues in each physical queu	  int numPrec;		        // the number of virtual queues in each physical queu
  phbParam phb_[MAX_CP];		// PHB table					  phbParam phb_[MAX_CP];		// PHB table
  int phbEntries;     		// the current number of entries in the PHB table	  int phbEntries;     		// the current number of entries in the PHB table
  int ecn_;			// used for ECN (Explicit Congestion Notification)	  int ecn_;			// used for ECN (Explicit Congestion Notification)
  LinkDelay* link_;		// outgoing link					  LinkDelay* link_;		// outgoing link
  int schedMode;                  // the Queue Scheduling mode				  int schedMode;                  // the Queue Scheduling mode

  int queueWeight[MAX_QUEUES];    // A queue weight per queue				  int queueWeight[MAX_QUEUES];    // A queue weight per queue
  double queueMaxRate[MAX_QUEUES];   // Maximum Rate for Priority Queueing		  double queueMaxRate[MAX_QUEUES];   // Maximum Rate for Priority Queueing
  double queueAvgRate[MAX_QUEUES];   // Average Rate for Priority Queueing		  double queueAvgRate[MAX_QUEUES];   // Average Rate for Priority Queueing
  double queueArrTime[MAX_QUEUES];	  // Arrival Time for Priority Queueing		  double queueArrTime[MAX_QUEUES];	  // Arrival Time for Priority Queueing
  int slicecount[MAX_QUEUES];								  int slicecount[MAX_QUEUES];
  int pktcount[MAX_QUEUES];								  int pktcount[MAX_QUEUES];
  int wirrTemp[MAX_QUEUES];								  int wirrTemp[MAX_QUEUES];
  unsigned char wirrqDone[MAX_QUEUES];							  unsigned char wirrqDone[MAX_QUEUES];
  int queuesDone;									  int queuesDone;
  											  
  void reset();										  void reset();
  void edrop(Packet* p); // used so flowmonitor can monitor early drops			  void edrop(Packet* p); // used so flowmonitor can monitor early drops
  void enque(Packet *pkt); // enques a packet						  void enque(Packet *pkt); // enques a packet
  Packet *deque(void);	// deques a packet						  Packet *deque(void);	// deques a packet
  int getCodePt(Packet *p); // given a packet, extract the code point marking from it	  int getCodePt(Packet *p); // given a packet, extract the code point marking from it
  int selectQueueToDeque();	// round robin scheduling dequing algorithm		  int selectQueueToDeque();	// round robin scheduling dequing algorithm
  void lookupPHBTable(int codePt, int* queue, int* prec); // looks up queue and prec 	  void lookupPHBTable(int codePt, int* queue, int* prec); // looks up queue and prec 
  void addPHBEntry(int codePt, int queue, int prec); // edits phb entry in the table	  void addPHBEntry(int codePt, int queue, int prec); // edits phb entry in the table
  void setNumPrec(int curPrec);								  void setNumPrec(int curPrec);
  void setMREDMode(const char* mode, const char* queue);				  void setMREDMode(const char* mode, const char* queue);
  void printStats(); // print various stats						  void printStats(); // print various stats
  double getStat(int argc, const char*const* argv);					  double getStat(int argc, const char*const* argv);
  void printPHBTable();  // print the PHB table						  void printPHBTable();  // print the PHB table
  void setSchedularMode(const char* schedtype); // Sets the schedular mode		  void setSchedularMode(const char* schedtype); // Sets the schedular mode

  // Add a weigth to a WRR or WIRR queue						  // Add a weigth to a WRR or WIRR queue
  void addQueueWeights(int queueNum, int weight); 					  void addQueueWeights(int queueNum, int weight); 
  // Add a maxRate to a PRI queue							  // Add a maxRate to a PRI queue
  void addQueueRate(int queueNum, int rate); 						  void addQueueRate(int queueNum, int rate); 

  void printWRRcount();		// print various stats					  void printWRRcount();		// print various stats

  // apply meter to calculate average rate of a PRI queue				  // apply meter to calculate average rate of a PRI queue
  // Modified by xuanc(xuanc@isi.edu) Oct 18, 2001, 					  // Modified by xuanc(xuanc@isi.edu) Oct 18, 2001, 
  // referring to the patch contributed by 						  // referring to the patch contributed by 
  // Sergio Andreozzi <sergio.andreozzi@lut.fi>						  // Sergio Andreozzi <sergio.andreozzi@lut.fi>
  void applyTSWMeter(int q_id, int pkt_size); 						  void applyTSWMeter(int q_id, int pkt_size); 
										      <
  detailedStatType *getDS(int flow_id, int cp);					      <
  void createDetailedStats();							      <
  void clearDetailedStats();							      <
  void dumpDetailedStats();							      <
};											};

#endif											#endif
