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

/* Modified and extended 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.
*/

/*
 * Copyright (C) 2000 by USC/ISI
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation, advertising
 * materials, and other materials related to such distribution and use
 * acknowledge that the software was developed by the University of
 * Southern California, Information Sciences Institute.  The name of the
 * University may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * $Header: /nfs/jade/vint/CVSROOT/ns-2/routing/rtmodule.h,v 1.13 2002/09/18 05:41:52 sundarra Exp $
 *
 * Definition of RoutingModule, base class for all extensions to routing
 * functionality in a Node. These modules are meant to be "plugin", and
 * should be configured via node-config{} interface in tcl/lib/ns-lib.tcl.
 */

#ifndef ns_rtmodule_h
#define ns_rtmodule_h

#include <tclcl.h>
#include "addr-params.h"
#include "classifier.h"
#include "classifier-hash.h"
#include "classifier-hier.h"

// P.M. & P.B. modifications
#include "classifier-umts.h"

class NsObject;
class Node;
class VirtualClassifier;
class DestHashClassifier;


class RoutingModule : public TclObject {
public:
	RoutingModule();
	/*
	 * Returns the node to which this module is attached.
	 */
	inline Node* node() { return n_; }
	/*
	 * Node-related module-specific initialization can be done here.
	 * However: (1) RoutingModule::attach() must be called from derived
	 * class so the value of n_ is setup, (2) module-specific
	 * initialization that does not require knowledge of Node should
	 * always stay in the module constructor.
	 *
	 * Return TCL_ERROR if initialization fails.
	 */
	virtual int attach(Node *n) { n_ = n; return TCL_OK; }
	virtual int command(int argc, const char*const* argv);
	virtual const char* module_name() const { return NULL; }

	/* support for populating rtg table */
	void route_notify(RoutingModule *rtm);
	void unreg_route_notify(RoutingModule *rtm);
	virtual void add_route(char *dst, NsObject *target);
	virtual void delete_route(char *dst, NsObject *nullagent);
	void set_table_size(int nn);
	void set_table_size(int level, int csize);
	RoutingModule *next_rtm_;

protected:
	Node *n_;
	Classifier *classifier_;
};

class BaseRoutingModule : public RoutingModule {
public:
	BaseRoutingModule() : RoutingModule() {}
	virtual const char* module_name() const { return "Base"; }
	virtual int command(int argc, const char*const* argv);
protected:
	DestHashClassifier *classifier_;
};

class McastRoutingModule : public RoutingModule {
public:
	McastRoutingModule() : RoutingModule() {}
	virtual const char* module_name() const { return "Mcast"; }
	virtual int command(int argc, const char*const* argv);
protected:
	DestHashClassifier *classifier_;
};

class HierRoutingModule : public RoutingModule {
public:
	HierRoutingModule() : RoutingModule() {}
	virtual const char* module_name() const { return "Hier"; }
	virtual int command(int argc, const char*const* argv);
protected:
	HierClassifier *classifier_;
};

// P.M. & P.B. modifications
class UmtsRoutingModule : public RoutingModule {
public:
	UmtsRoutingModule() : RoutingModule() {}
	virtual const char* module_name() const { return "Umts"; }
	virtual int command(int argc, const char*const* argv);
protected:
	UmtsClassifier *classifier_;
};

class ManualRoutingModule : public RoutingModule {
public:
	ManualRoutingModule() : RoutingModule() {}
	virtual const char* module_name() const { return "Manual"; }
	virtual int command(int argc, const char*const* argv);
	void add_route(char *dst, NsObject *target);
protected:
	DestHashClassifier *classifier_;
};

class SourceRoutingModule : public RoutingModule {
public:
        SourceRoutingModule() : RoutingModule() {}
        virtual const char* module_name() const { return "Source"; }
	virtual int command(int argc, const char*const* argv);
};

class VcRoutingModule : public RoutingModule {
public:
	VcRoutingModule() : RoutingModule() {}
	virtual const char* module_name() const { return "VC"; }
	virtual int command(int argc, const char*const* argv);
	virtual void add_route(char *, NsObject *);
};



class PgmRoutingModule : public RoutingModule {
public:
        PgmRoutingModule() : RoutingModule() {}
        virtual const char* module_name() const { return "PGM"; }
};

class LmsRoutingModule : public RoutingModule {
public:
	LmsRoutingModule() : RoutingModule() {}
	virtual const char* module_name() const { return "LMS"; }
	// virtual int command(int argc, const char*const* argv);
	virtual void add_route(char *dst, NsObject *target){}
};

#endif //  ns_rtmodule_h
